🙋♂️ Ref Lecture
function add (a, b) { // warning - 타입 지정
return a + b
}
함수 인자는 기본적으로 any 타입이라, 타입을 지정하는 것을 권장함.
const sub = (a: number, b: number): number => a - b;
-> 이것이 바로 함수의 Call Signature 이다.
type Add = (a:number, b:number) => number;
const add: Add = (a, b) => a + b;
overloading은 함수가 서로다른 여러개의 call signiture을 가질 때 발생함.
함수의 콜 시그니처를 아래와 같이 작성할수도 있음.
type Add = {
(a: number, b: number) : number
}
만약, 여러개의 call signiture이 있다면?
type Add = {
(a: number, b: number) : number
(a: number, b: string) : number
}
const add: Add = (a, b) => a + b // a: number 인데, b: string | number 임.
// number과 string은 더해서 number이 될 수 없으므로 에러가 발생함.
위와 같이 call signiture가 여러개라 혼란이 올 수 있는 상황에서는
if문으로 분기를 해줘야 한다.
const add: Add = (a, b) => {
if(typeof b === 'string') return a
return a + b
}
BUT. 위와 같은 경우는 아주 안좋은 경우임.
같은 함수에서 인자로 string이 들어갈수도, 객체가 들어갈수도 있게 하려면?
-> 예시❗️ Next.js의 Router.push 함수
Router.push('/home'); // string을 전달해줌
Router.push({ // object를 전달해줌
path: '/home',
state: 1
});
위와 같은 경우에는 타입을 아래처럼 설정하면 됨.
type Config = {
path: string
state: object
}
type Push = {
(path: string): void
(config: Config): void
}
const push: Push = (config) => {
if(typeof config === 'string') {
console.log(config);
// 문자열인 경우
} else {
console.log(config.path);
// 객체인 경우
}
}
Add 함수 응용
- 파라미터 개수를 다르게 할 수 있음.
type Add = { (a: number, b: number): number (a: number, b: number, c: number): number }
🔻
type Add = {
(a: number, b: number): number;
(a: number, b: number, c: number): number;
};
const add: Add = (a, b, c?: number) => {
if (c) return a + b + c;
return a + b;
};
add(1, 2); // 3
add(1, 2, 3); // 6
✅ 다형성(polymorphism) 이란?
- 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미
type PrintArr = {
(arr: number[]): void
}
const printArray: PrintArr = (arr) => {
arr.forEach(i => console.log(i);
}
type PrintArr = {
(arr: number[]): void;
(arr: boolean[]): void;
(arr: string[]): void;
};
const printArray: PrintArr = (arr) => {
arr.forEach((i) => console.log(i));
};
printArray([1, 2, 3]);
printArray([true, true, false]);
printArray(['a','b', 'c']);
만약 number, boolean, string 에 대한 각각의 call signature을 선언해주면
아래와 같은 경우에는 오류가 발생한다.
printArray(['1', 'a', true]); // ❗️ error
❗️ 참고
(arr: (number | string | boolean)[]): void
위와 같이 OR 기호 이용시 가능하지만, 위와같은 방법은 모든 경우를 다 따져야 하므로 권장하지 않음
🔻
대신, generic
을 사용하자.
// 🔻 Generic 사용
type PrintArr = {
<TypePlaceholder>(arr: TypePlaceholder[]): void
};
const printArray: PrintArr = (arr) => {
arr.forEach((i) => console.log(i));
};
printArray([1, 2, 3]);
printArray([true, true, false]);
printArray(['a', 'b', 'c']);
printArray([1, 'a', true]); // error 발생하지 X.
위와 같이 <generic>(arr: generic[])
형태로 함수 call signature이 나온다.
type PrintArr = {
<TypePlaceholder>(arr: TypePlaceholder[]): TypePlaceholder
};
const printArray: PrintArr = (arr) => {
return arr[0];
};