[Typescript] Call signature, Overloading, Generic
Call signature
함수의 파라미터와 리턴값의 타입을 모두 미리 선언하는 것이다.
예를들어 React에서 함수로 prop을 보낼때, 어떻게 작동할지 미리 설계 해놓을 수 있다.
1
2
3
4
5
type Add = (a: number, b: number) => number; // this is a Call signature
const add: Add = (a, b) => {
return a + b;
};
Overloading
오버로딩은 함수가 여러개의 call signature를 가지고 있을때 사용한다.
이런 경우의 타입을 직접 정의하는 일은 거의 없고,
라이브러리나 패키지들이 오버로딩 개념을 많이 사용하므로 알고있자.
1
2
3
4
5
6
7
8
9
10
type Add = {
(a: number, b: number): number
(a: number, b: string): number // 실용성이 없는 코드이지만 오버로딩의 핵심을 보여준다.
}
const add: Add = (a, b) => {
// b는 number일수도, string일수도 있으므로 조건문이 필요하다
if(typeof b == 'string') return a;
return a + b
}
파라미터의 갯수가 다른 경우도 있을 수 있다.
1
2
3
4
5
6
7
8
9
10
type Add = {
(a: number, b: number): number
(a: number, b: number, c: number): number
}
const add: Add = (a, b, c?: number) => {
// c는 옵셔널한 파라미터이므로, 따로 타입을 적어준다.
if(c) return a + b + c
return a + b
}
1
2
// 위에서 오버로딩으로 정의된 Add 타입과 아래 타입은 결국 같다
type Add = (a: number, b: number, c?: number) => number;
Generic
함수가 사용할 타입을 미리 정해놓지 않고, 그 함수를 사용할 때 결정할 수 있도록 하는 TS 문법이다.
함수에서 다양한 타입이 필요한 경우, 모든 경우의 수에 해당하는 Call signature를 정의해놓는 것은 번거롭다.
함수의 타입을 generic으로 설정해놓으면, 함수가 사용될때 타입을 알아서 유추하도록 할 수 있다.
1
2
3
4
5
6
7
8
9
10
type SuperPrint = {
<T>(arr: T[]): T,
// 꺽쇠괄호 안에 generic 이름을 만들어주고, 필요한 곳에 사용한다. (두개도 가능)
};
const superPrint: SuperPrint = (arr) => arr[0]; // 배열의 첫번째 아이템을 보내주는 함수로 정의
superPrint([1, 2, 3]); // (arr: number[]) => number
superPrint(["a", "b", "c"]); // (arr: string[]) => string
superPrint([1, "a", 2, "b"]); // (arr: (string | number)[]) => string | number
어떤 데이터 타입이든 들어갈 수 있다는 점이 any와 비슷하지만,
any는 타입을 특정하지 않아 TS의 제어를 벗어난다는 뜻이고,
generic을 활용하는 것은 상황에 맞게 타입을 유추해 적용한다는 뜻이다.
Leave a comment