문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판이전 판다음 판 | 이전 판 | ||
| typescript:function [2019/07/27 14:56] – [Introduction] taekgu | typescript:function [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1 | ||
|---|---|---|---|
| 줄 5: | 줄 5: | ||
| JavaScript의 Function은 application의 기초적인 block을 만든다. 이 것을 통해서 abstraction, | JavaScript의 Function은 application의 기초적인 block을 만든다. 이 것을 통해서 abstraction, | ||
| - | ==== Functions ==== | + | ===== Functions |
| 시작하기, | 시작하기, | ||
| 줄 22: | 줄 22: | ||
| JavaScript와 마찬가지로 함수는 함수 본문 외부의 변수를 참조 할 수 있습니다. 그들은 그렇게 할 때 이러한 변수를 포착(capture)한다고 합니다. 이것이 어떻게 작동하는지 (그리고이 기술을 사용할 때의 절충)는 이 기사의 범위를 벗어나는 것이지만, | JavaScript와 마찬가지로 함수는 함수 본문 외부의 변수를 참조 할 수 있습니다. 그들은 그렇게 할 때 이러한 변수를 포착(capture)한다고 합니다. 이것이 어떻게 작동하는지 (그리고이 기술을 사용할 때의 절충)는 이 기사의 범위를 벗어나는 것이지만, | ||
| - | < | + | < |
| let z = 100; | let z = 100; | ||
| function addToZ(x, y) { | function addToZ(x, y) { | ||
| 줄 29: | 줄 29: | ||
| </ | </ | ||
| + | |||
| + | ===== Function Types ===== | ||
| + | ==== Typing the function ==== | ||
| + | 이전 단순한 예제에 타입을 추가해보자 | ||
| + | <code javascript> | ||
| + | function add(x: number, y: number): number { | ||
| + | return x + y; | ||
| + | } | ||
| + | let myAdd = function(x: number, y: number): number { return x + y; }; | ||
| + | </ | ||
| + | 매개변수 각각의 타입과 그리고 함수 자체의 반환 타입을 추가 할 수 있다.TypeScript는 return 문을 보고 리턴 유형을 파악할 수 있으므로 많은 경우에 선택적으로 남겨 둘 수 있습니다. | ||
| + | |||
| + | ==== Writing the function type ==== | ||
| + | 이제는 함수를 타이프했습니다. 함수 타입의 각 부분을 살펴봄으로써 함수의 전체 유형을 작성해 봅시다. | ||
| + | <code javascript> | ||
| + | let myAdd: (x: number, y: number) => numbe = | ||
| + | function(x: number, y: number): number { return x + y; }; | ||
| + | </ | ||
| + | |||
| + | 함수의 형식은 인수의 형식과 반환 형식의 두 부분이 동일합니다. 전체 함수 유형을 작성할 때 두 부분이 필요합니다. 매개 변수 유형을 매개 변수 목록과 같이 작성하여 각 매개 변수에 이름과 유형을 지정합니다. 이 이름은 가독성을 돕기위한 것입니다. 대신에 다음과 같이 쓸 수 있습니다. | ||
| + | <code javascript> | ||
| + | let myAdd: (baseValue: number, increment: number) => number = | ||
| + | function(x: number, y: number): number { return x + y; }; | ||
| + | </ | ||
| + | |||
| + | 매개 변수 유형이 정렬되어있는 한, 함수 유형에 매개 변수를 지정하는 이름에 관계없이 함수의 유효한 유형으로 간주됩니다. | ||
| + | |||
| + | 두 번째 부분은 반환 유형입니다. 매개 변수와 반환 유형 사이에 굵은 화살표 (=>)를 사용하여 반환 유형을 명확하게합니다. 앞에서 언급했듯이 이것은 함수 유형에서 필수적인 부분이므로 함수가 값을 반환하지 않으면 이것를 끄는 대신에 void를 사용합니다. | ||
| + | |||
| + | 매개변수와 반환유형만 함수 유형을 구성합니다. 캡처된 변수는 유형에 반영되지 않습니다. 실제로 캡처된 변수는 함수의 " | ||
| + | |||
| + | ==== Inferring the types ==== | ||
| + | 이 예제를 가지고 노는 경우 TypeScript 컴파일러는 방정식의 한쪽에만 형식이 있어도 형식을 알아낼 수 있습니다. | ||
| + | |||
| + | <code javascript> | ||
| + | // myAdd has the full function type | ||
| + | let myAdd = function(x: number, y: number): number { return x + y; }; | ||
| + | |||
| + | // The parameters ' | ||
| + | let myAdd: (baseValue: number, increment: number) => number = | ||
| + | function(x, y) { return x + y; }; | ||
| + | </ | ||
| + | 이를 유형 추론의 한 형태 인 " | ||
| + | |||
| + | ===== Optional and Default Parameters ===== | ||
| + | TypeScript에서, | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | return firstName + " " + lastName; | ||
| + | } | ||
| + | |||
| + | let result1 = buildName(" | ||
| + | let result2 = buildName(" | ||
| + | let result3 = buildName(" | ||
| + | </ | ||
| + | 자바 스크립트에서 모든 매개 변수는 선택 사항이며 사용자는 적합하다고 판단되는 매개 변수를 그대로 둘 수 있습니다. 그들이 할 때, 그들의 값은 undefined입니다. 우리는 TypeScript에서 매개 변수의 끝에 ''?'' | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | if (lastName) | ||
| + | return firstName + " " + lastName; | ||
| + | else | ||
| + | return firstName; | ||
| + | } | ||
| + | |||
| + | let result1 = buildName(" | ||
| + | let result2 = buildName(" | ||
| + | let result3 = buildName(" | ||
| + | </ | ||
| + | 선택적 매개변수는 필수 매개변수에 뒤에 따라야 합니다. lastName보다 firstName을 선택적으로 만들고 싶으면 함수의 매개변수 순서를 변경해야하며 목록에서 firstName을 마지막에 넣어야 합니다. | ||
| + | |||
| + | TypeScript에서 사용자가 매개 변수를 제공하지 않거나 사용자가 그 자리에 undefined를 전달하면 매개 변수가 할당되는 값을 설정할 수도 있습니다. 이를 기본 초기화 매개 변수라고합니다. 앞의 예제를 취하고 성을 기본값으로 " | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | return firstName + " " + lastName; | ||
| + | } | ||
| + | |||
| + | let result1 = buildName(" | ||
| + | let result2 = buildName(" | ||
| + | let result3 = buildName(" | ||
| + | let result4 = buildName(" | ||
| + | </ | ||
| + | |||
| + | 모든 필수 매개 변수 다음에 오는 기본 초기화 매개 변수는 선택적 매개 변수처럼 취급되며 선택적 매개 변수와 마찬가지로 해당 함수를 호출 할 때 생략 할 수 있습니다. 이는 선택적 매개 변수를 의미하며 후행 기본 매개 변수는 해당 유형에서 공통성을 공유하므로 둘 다 | ||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | // ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | // ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName = " | ||
| + | return firstName + " " + lastName; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Rest Parameters ===== | ||
| + | 필수 매개 변수, 선택적 매개 변수 및 디폴드 매개 변수는 모두 한 가지 공통점이 있습니다. 한 번에 하나의 매개 변수에 대해 설명합니다. 때로는 여러 매개 변수를 그룹으로 사용하거나 함수가 궁극적으로 취할 매개 변수의 수를 모를 수 있습니다. JavaScript에서는 모든 함수 본문에서 볼 수있는 arguments 변수를 사용하여 인수를 직접 사용할 수 있습니다. | ||
| + | |||
| + | TypeScript에서는 다음 인수를 함께 변수로 수집 할 수 있습니다. | ||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | return firstName + " " + restOfName.join(" | ||
| + | } | ||
| + | |||
| + | // employeeName will be " | ||
| + | let employeeName = buildName(" | ||
| + | </ | ||
| + | |||
| + | 나머지 매개 변수는 무한한 수의 선택적 매개 변수로 처리됩니다. rest 매개 변수에 인수를 전달할 때 원하는 만큼 사용할 수 있습니다. 너는 아무도 지나칠 수 없다. 컴파일러는 **ellipsis[줄임표] ('' | ||
| + | |||
| + | 줄임표는 나머지 매개 변수가 있는 함수의 유형에도 사용됩니다. | ||
| + | |||
| + | <code javascript> | ||
| + | function buildName(firstName: | ||
| + | return firstName + " " + restOfName.join(" | ||
| + | } | ||
| + | |||
| + | let buildNameFun: | ||
| + | </ | ||
| + | |||
| + | ===== this ===== | ||
| + | |||
| + | JavaScript에서 '' | ||
| + | |||
| + | ==== this and arrow functions ==== | ||
| + | JavaScript에서 '' | ||
| + | |||
| + | 예제를 살펴 보겠습니다: | ||
| + | <code javascript> | ||
| + | let deck = { | ||
| + | suits: [" | ||
| + | cards: Array(52), | ||
| + | createCardPicker: | ||
| + | return function() { | ||
| + | let pickedCard = Math.floor(Math.random() * 52); | ||
| + | let pickedSuit = Math.floor(pickedCard / 13); | ||
| + | |||
| + | return {suit: this.suits[pickedSuit], | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | let cardPicker = deck.createCardPicker(); | ||
| + | let pickedCard = cardPicker(); | ||
| + | |||
| + | alert(" | ||
| + | </ | ||
| + | |||
| + | createCardPicker는 그 자체로 함수를 반환하는 함수입니다. 예제를 실행하려고하면 예상되는 경고 상자 대신 오류가 발생합니다. 이것은 createCardPicker에 의해 생성된 함수에서 사용되는 this가 deck 객체 대신 window로 설정되기 때문입니다. 그 이유는 우리가 cardPicker()를 단독 호출하기 때문입니다. 이와 같은 최상위 비메소드 구문 호출은 window를 사용합니다. (참고 : strict mode하에서 '' | ||
| + | |||
| + | 나중에 사용할 함수를 반환하기 전에 함수가 '' | ||
| + | |||
| + | <code javascript> | ||
| + | let deck = { | ||
| + | suits: [" | ||
| + | cards: Array(52), | ||
| + | createCardPicker: | ||
| + | // NOTE: the line below is now an arrow function, allowing us to capture ' | ||
| + | return () => { | ||
| + | let pickedCard = Math.floor(Math.random() * 52); | ||
| + | let pickedSuit = Math.floor(pickedCard / 13); | ||
| + | |||
| + | return {suit: this.suits[pickedSuit], | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | let cardPicker = deck.createCardPicker(); | ||
| + | let pickedCard = cardPicker(); | ||
| + | |||
| + | alert(" | ||
| + | </ | ||
| + | 더 좋게도, 컴파일러에 --noImplicitThis 플래그를 전달하면이 실수를 할 때 TypeScript가 경고합니다. this.suits [pickedSuit]의 this는 any 유형입니다. | ||
| + | |||
| + | ==== this parameters ==== | ||
| + | 불행히도 this.suits [pickedSuit]의 유형은 여전히 any입니다. 이는 객체 리터럴 내부의 함수 표현식에서 비롯 되었기 때문입니다. 이 문제를 해결하려면이 매개 변수를 명시적으로 제공 할 수 있습니다. 이 매개 변수는 함수의 매개 변수 목록에서 처음 나오는 가짜 매개 변수입니다. | ||
| + | |||
| + | <code javascript> | ||
| + | function f(this: void) { | ||
| + | // make sure `this` is unusable in this standalone function | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 위의 예인 Card와 Deck에 몇 가지 인터페이스를 추가하여 유형을 명확하고 쉽게 재사용 할 수 있게 하십시오. | ||
| + | |||
| + | <code javascript> | ||
| + | interface Card { | ||
| + | suit: string; | ||
| + | card: number; | ||
| + | } | ||
| + | interface Deck { | ||
| + | suits: string[]; | ||
| + | cards: number[]; | ||
| + | createCardPicker(this: | ||
| + | } | ||
| + | let deck: Deck = { | ||
| + | suits: [" | ||
| + | cards: Array(52), | ||
| + | // NOTE: The function now explicitly specifies that its callee must be of type Deck | ||
| + | createCardPicker: | ||
| + | return () => { | ||
| + | let pickedCard = Math.floor(Math.random() * 52); | ||
| + | let pickedSuit = Math.floor(pickedCard / 13); | ||
| + | |||
| + | return {suit: this.suits[pickedSuit], | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | let cardPicker = deck.createCardPicker(); | ||
| + | let pickedCard = cardPicker(); | ||
| + | |||
| + | alert(" | ||
| + | </ | ||
| + | |||
| + | 이제 TypeScript는 createCardPicker가 Deck 객체에서 호출 될 것으로 예상합니다. 즉, 이것은 Deck 형식이므로 아무 것도 아니므로 --noImplicitThis는 오류를 발생시키지 않습니다. | ||
| + | |||
| + | ==== this parameters in callbacks ==== | ||
| + | 나중에 콜백 할 라이브러리에 함수를 전달할 때 콜백에서 '' | ||
| + | |||
| + | <code javascript> | ||
| + | interface UIElement { | ||
| + | addClickListener(onclick: | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code javascript> | ||
| + | class Handler { | ||
| + | info: string; | ||
| + | onClickBad(this: | ||
| + | // oops, used `this` here. using this callback would crash at runtime | ||
| + | this.info = e.message; | ||
| + | } | ||
| + | } | ||
| + | let h = new Handler(); | ||
| + | uiElement.addClickListener(h.onClickBad); | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code javascript> | ||
| + | class Handler { | ||
| + | info: string; | ||
| + | onClickGood(this: | ||
| + | // can't use `this` here because it's of type void! | ||
| + | console.log(' | ||
| + | } | ||
| + | } | ||
| + | let h = new Handler(); | ||
| + | uiElement.addClickListener(h.onClickGood); | ||
| + | </ | ||
| + | onClickGood는이 유형을 this: void로 지정하기 때문에 addClickListener에 전달할 수 있습니다. 물론 이것은 this.info를 사용할 수 없다는 것을 의미합니다. 둘 다 원한다면 화살표 함수를 사용해야합니다. | ||
| + | <code javascript> | ||
| + | class Handler { | ||
| + | info: string; | ||
| + | onClickGood = (e: Event) => { this.info = e.message } | ||
| + | } | ||
| + | </ | ||
| + | 이것은 화살표 함수가 this를 사용하기 때문에 작동합니다. 그래서 당신은 항상 이것을 기대하는 무언가에 전달할 수 있습니다 this: void. 단점은 처리기 유형의 객체 당 하나의 화살표 함수가 작성된다는 것입니다. 한편, 메소드는 한 번만 작성되어 Handler의 프로토 타입에 첨부됩니다. 핸들러 유형의 모든 객체간에 공유됩니다. | ||
| + | |||
| + | ===== Overloads ===== | ||
| + | <code javascript> | ||
| + | let suits = [" | ||
| + | |||
| + | function pickCard(x: {suit: string; card: number; }[]): number; | ||
| + | function pickCard(x: number): {suit: string; card: number; }; | ||
| + | function pickCard(x): | ||
| + | // Check to see if we're working with an object/ | ||
| + | // if so, they gave us the deck and we'll pick the card | ||
| + | if (typeof x == " | ||
| + | let pickedCard = Math.floor(Math.random() * x.length); | ||
| + | return pickedCard; | ||
| + | } | ||
| + | // Otherwise just let them pick the card | ||
| + | else if (typeof x == " | ||
| + | let pickedSuit = Math.floor(x / 13); | ||
| + | return { suit: suits[pickedSuit], | ||
| + | } | ||
| + | } | ||
| + | |||
| + | let myDeck = [{ suit: " | ||
| + | let pickedCard1 = myDeck[pickCard(myDeck)]; | ||
| + | alert(" | ||
| + | |||
| + | let pickedCard2 = pickCard(15); | ||
| + | alert(" | ||
| + | </ | ||
| + | 컴파일러가 올바른 유형 검사를 선택하기 위해 기본 JavaScript와 비슷한 과정을 거칩니다. 오버로드 목록을보고 첫 번째 오버로드로 진행하여 제공된 매개 변수를 사용하여 함수를 호출합니다. 일치하는 것을 찾으면, | ||
| + | |||
| + | pickCard(x) 함수는 모든 객체가 오버로드리스트의 일부가 아니므로 객체를 취하는 오버로드와 숫자를 취하는 오버로드의 두 가지 오버로드 만 있습니다. 다른 매개 변수 유형으로 pickCard를 호출하면 오류가 발생합니다. | ||
| + | |||
| + | ==== 예제 ==== | ||
| + | <code javascript> | ||
| + | function add(a: string, b: string): string; | ||
| + | function add(a: number, b: number): string; | ||
| + | function add(a, b): any { | ||
| + | return a + b; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 함수명과 매개변수의 개수는 같지만 타입을 다른 경우. | ||
| + | 다른 언어의 오버로드는 함수명만 동일하면 되지만 TypeScript의 오버로딩은 함수명과 매개변수의 갯수가 같아야 한다. | ||