문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판이전 판다음 판 | 이전 판 | ||
| typescript:function [2019/07/27 15:40] – [this] taekgu | typescript:function [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1 | ||
|---|---|---|---|
| 줄 67: | 줄 67: | ||
| let myAdd = function(x: number, y: number): number { return x + y; }; | let myAdd = function(x: number, y: number): number { return x + y; }; | ||
| - | // The parameters ' | + | // The parameters ' |
| let myAdd: (baseValue: number, increment: number) => number = | let myAdd: (baseValue: number, increment: number) => number = | ||
| function(x, y) { return x + y; }; | function(x, y) { return x + y; }; | ||
| 줄 160: | 줄 160: | ||
| ===== this ===== | ===== 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의 오버로딩은 함수명과 매개변수의 갯수가 같아야 한다. | ||