[typescript] 타입스크립트 함수
타입스크립트 함수
타입스크립트의 함수(Functions) 에 대해 알아봅니다. ES6와 작성하는 방법은 크게 다르지 않습니다. 좀 더 타입에 대해 명확해졌을 뿐입니다.
📝 목차
함수작성
타입스크립트에서 함수작성하는 방법을 살펴보면 ES6와 크게 다르지않습니다. 매개변수의 타입과 return 타입에 대해 정해줄 뿐입니다.
// ES6function add(num1 num2) {return num1 + num2;}// TSfunction add(num1: number num2: number): number {return num1 + num2;}
ES6 문법에서도 함수의 역할을 잘(?) 하고있습니다. 하지만 의도치않게 string 이 넘어와버리면 문자열로 인식하여 concat 이 되어버려 기상천외한 값이 나오게됩니다.
타입스크립트에서는 이를 막기위해 컴파일타임에 타입을 검사합니다. num1
과 num2
는 number 타입이며 반환값도 number 타입임을 알려줍니다.
이렇게도 쓸 수 있습니다.
// TSconst add = (num1: number num2: number): number => num1 + num2;
Default Parameter
기본 매개변수입니다. 매개변수에 값을 전달하지 않았을 시 나타나는 undefined
대신 기본 값으로 초기화를 해줍니다. 타입스크립트에서도 지원합니다.
// TSfunction add(num1: number = 0 num2: number = 0): number {return num1 + num2;}
Optional Parameter
선택적 매개변수입니다. 인터페이스에서의 선택적 프로퍼티처럼 매개변수의 값이 있을수도 있고 없을수도 있는 상황에서 사용합니다. ?
를 이용하여 선택적인 매개변수로 지정할 수 있습니다.
// TSfunction greet(lastName: string firstName?: string): string {let message = `my name is `;if(firstName) {message += firstName;}return message;}consolelog(greet('heecheol' 'kim')); // my name is heecheolkimconsolelog(greet('heecheol')); // my name is heecheol
주의할점이 있다면 선택적 매개변수는 오른쪽 정렬하여 등록해줘야 합니다.
// TSfunction greet(lastName: string firstName?: string): string { ... } // (O)function greet(firstName?: string lastName: string): string { ... } // (X)
Rest Parameter
나머지 매개변수입니다. ES6 에서의 ...(스프레드 연산자)
를 통해 타입스크립트에서도 동일하게 사용할 수 있습니다. 스프레드 연산자는 배열이므로 타입을 지정해줄 때 배열임을 명시해줍니다.
// TSfunction nameListBuilder(...nameList: string[]) {// ...}
Union Type
타입스크립트에서는 함수의 매개변수나 리턴타입을 정할 때 두가지 이상의 타입일 수 있습니다. 이럴 때 유니온타입을 사용합니다.
// TSfunction numberOrString(data: number | string) {if(typeof data == 'number') {// ...} else if(typeof data == 'string') {// ...}}
아직까지는 어떻게 사용되는지 잘 모르겠습니다. 타입스크립트로 프로젝트를 진행하며 필요한 경우가 있다면 추후 포스팅하겠습니다.
Overloading
자바스크립트는 원래 오버로딩이 구현이 안되었습니다. 타입스크립트를 쓴다고 구현이 되는것은 아니지만 비슷하게 구현할 수 있습니다.
// TSfunction greetBuilder(firstName: string age?: number): void;function greetBuilder(firstName: string age: string): void;function greetBuilder(firstName: string age: number | string): any {let message = `Hi My Name is `;if(typeof age == 'number') {message += `, years old at next year`;} else if(typeof age == 'string') {message += `, years old.`;}return message;}consolelog(greetBuilder('kim')); // Hi My Name is kimconsolelog(greetBuilder('kim' 24)); // Hi My Name is kim, 25 years old at next yearconsolelog(greetBuilder('kim' '24')); // Hi My Name is kim, 24 years old.
greetBuilder
라는 함수 시그니쳐가 세개이지만 구현은 마지막에서 하고 있습니다. 구현에서 각 타입에 맞게 분기를 타 반환하는 것을 볼 수 있습니다.
this
자바스크립트에서 this
는 어떻게 사용하는지에 따라 각각 다릅니다. 대표적으로 4가지가 있습니다.
- 생성자의 this
- 함수실행의 this
- 객체의 메서드로서의 this
- call, bind, apply 에서의 this
여기서 함수실행의 this 와 객체의 메서드로서의 this 의 차이를 잘 알아야합니다. 다음 코드는 에러를 뱉습니다.
// TSconst lotDrawing = {nameList: ['kim' 'hee' 'cheol' 'man']drawing: function() {return function() {let pickedName = Mathfloor(Mathrandom() * 4);return {name: thisnameList[pickedName]};}}};let nameGenerator = lotDrawingdrawing();let who = nameGenerator();consolelog(who);
console.log(who)
가 나오기전에 런타임 에러가 나오는것을 볼 수 있습니다.
에러의 원인
에러의 원인은 drawing
메서드 내에 있습니다. drawing
내부에서 함수를 반환합니다. 이 '함수'를 반환하는것이 원인입니다. 자바스크립트에서 함수실행에서의 this 는 global 객체
입니다. 그렇기 때문에 기대했던 this
는 lotDrawing.nameList
가 아니라는 것입니다.
화살표 함수
ES6 에서 화살표함수를 통해 this
를 바인딩합니다.
// TSconst lotDrawing = {nameList: ['kim' 'hee' 'cheol' 'man']drawing: function() {return () => {let pickedName = Mathfloor(Mathrandom() * 4);return {name: thisnameList[pickedName]};}}};let nameGenerator = lotDrawingdrawing();let who = nameGenerator();consolelog(who); // {name: "hee"}// lotDrawing.nameList 중 하나가 랜덤으로 출력
화살표 함수를 통해 this
를 바인딩하여 넘겨줍니다.
this 파라미터
this 를 파라미터로 지정할 수 있습니다. 이렇게 하면 명시적으로 해당 함수에서의 this 가 어떤 것을 가리키는지 알 수 있습니다. interface 를 같이 사용하면 다음과 같습니다.
// TSinterface Person {name: string;}interface LotDrawing {nameList: string[];drawing(this: LotDrawing): () => Person;}const lotDrawing: LotDrawing = {nameList: ['kim' 'hee' 'cheol' 'man']// 해당 메서드에서 this 는 LotDrawing 으로 예상됩니다.drawing: function(this: LotDrawing) {// 반환타입은 Personreturn (): Person => {let pickedName = Mathfloor(Mathrandom() * 4);return {name: thisnameList[pickedName]};}}};let nameGenerator = lotDrawingdrawing();let who = nameGenerator();consolelog(who); // {name: "hee"}// lotDrawing.nameList 중 하나가 랜덤으로 출력