- 타입스크립트의 함수
- 함수의 기본적인 타입 선언
- 함수의 인자
- REST 문법이 적용된 매개변수
- this
- 콜백에서의 this
- 출처
- 다른 언어의 함수와 동일하게 3가지 타입을 정의할 수 있다.
- 함수의 파라미터 타입 : 함수의 매개변수가 어떤 타입이어야 하는지 명시해야한다.
- 함수의 반환 타입 : 함수가 반환하는 값의 타입을 명시해야한다.
- 함수의 구조 타입 : 인터페이스를 통해, 함수의 구조를 정의할 수 있다.
- 기본적인 자바스크립트의 함수 선언은, 다음과 같다.
function foo(a, b) {
return a + b;
}
- 위 상황에서, a와 b에 어떤 값이 들어올지 모르며, 반환값 또한 어떤 값을 리턴할지 모른다.
- 타입스크립트를 이런 상황을 피하고자, 타입을 정의해야한다.
function foo(a: number, b: number): number {
return a + b;
}
만약 함수의 반환 값이 없다면, void를 사용해야한다.
- 자바에서의 함수형 인터페이스와 유사하게 함수의 구조를 정의할 수 있다.
interface Sum {
(a: number, b: number): number;
}
const sum: Sum = (a, b) => {return a + b;};
- 타입을 이용하면 다음과 같이 만들 수 있다.
type Sum = (a: number, b: number) => number;
const sum: Sum = (a, b) => {return a + b;};
- 타입스크립트에서는 함수의 인자를 모두 필수 값으로 간주며, 함수의 매개변수를 설정하면, undefined 또는 null이라도 인자로 넘겨야 한다. (컴파일러에서 정의된 매개변수의 값이 넘어왔는지 확인한다.)
function foo(a: number, b: number): number {return a + b;};
foo(1, 2); // ok
foo(1, 2, 3); // error
foo(1); // error
- 만약 매개변수의 갯수 만큼 인자를 넘기지 않아도 되는 자바스크립트의 특성을 살린다면, ?를 이용하면 된다.
- ?는 자바의 옵셔널과 동일하고, 만약 b가 undefined일 경우를 따로 처리해준다.
- (변수 ?? 타입값)으로 지정이 가능하다.
function foo(a: number, b?: number): number {return a + (b ?? 0);};
foo(1, 2); // ok
foo(1, 2, 3); // error
foo(1); // ok
- 이외에도 매개변수 초기화는 ES6 문법과 동일한다.
function foo(a: number, b = 100): number {return a + b;};
function foo(a: number, b:number = 100): number {return a + b;};
foo(1, undefined); // ok
foo(1, 2, 3); // error
foo(1); // ok
- REST 문법에도 타입스크립트에서 타입을 지정해주어야 한다.
function fooD(a: number, ...nums: number[]): number {
let totalOfNums: number = 0;
for (let key in nums) {
totalOfNums += nums[key];
}
return a + totalOfNums;
}
fooD(1, ...[1, 2, 3]);
- 내가 알고있던 this와 사뭇 달라서 this의 소개를 먼저 시작
- 자바에서 this는 현재 인스턴스를 참조하는데, this를 사용하면 생성자에서 다른 생성자를 호출하거나, 현재 인스턴스의 필드와 메서드에 접근할 수 있다. 또한 메서드 호출 방식에 따라 변경되지 않는다.
- 자바스크립트는 다르다. 함수 호출할 때, 컨텍스트에 따라 달라지는데, 함수 호출, 객체 메서드 호출, 생성자 함수 호출, call, apply, bind 등 다양한 상황에 따라 this가 바뀐다. -> 예측이 조금 불확실하다.
const hiBye = {
hi: 'hello',
bye: function() {
console.log(this.hi + "bye");
}
};
hiBye.bye(); // hellobye
const bye = hiBye.bte;
bye(); // undefined
-
작성을 해보아도, 위험한게 두눈으로 보인다.
-
타입 스크립트에서는 메서드 내에서 this의 타입을 명시적으로 지정할 수 있다.
// 콜백 함수에서의 this
class ClazzA {
a: number = 1;
go() {
const arr: number[] = [2, 3, 4];
arr.forEach(function (number: number) {
console.log(this.a + number);
});
}
}
// 화살표 함수
class ClazzB {
a: number = 1;
go() {
const arr: number[] = [2, 3, 4];
arr.forEach((number: number) => {
console.log(this.a + number);
});
}
}
- 콜백에서 this는 구분을 해줘야하는 상황이 존재하는데, 그럴땐 강제할 수 있다.
interface UIElement {
// 아래 함수의 `this: void` 코드는 함수에 `this` 타입을 선언할 필요가 없다는 의미입니다.
addClickListener(onclick: (this: void, e: Event) => void): void;
}
class Handler {
info: string;
onClick(this: void, e: Event) {
// `this`의 타입이 void이기 때문에 여기서 `this`를 사용할 수 없습니다.
console.log('clicked!');
}
}
let handler = new Handler();
uiElement.addClickListener(handler.onClick);
- 일단 정상적으로 확인 할 수 없는 코드이다. 빠진 부분도 많고, 글을 쓰신 의도는 이런식으로 작동합니다. 이므로, 의도를 파악하고 넘어가자..