
Call Signatures로 함수 타입 정의
Call Signature는 함수의 매개변수와 반환 값의 타입을 미리 정의하는 방법이다. IDE에서 함수에 마우스를 올렸을 때 보이는 타입 정보가 바로 Call Signatures이다.
기본적인 Call Signature 정의
// 함수 타입 정의
type Add = (a: number, b: number) => number;
// 실제 함수 구현
const add: Add = (a, b) => a + b;💡 매개변수 이름은 타입 정의와 실제 구현에서 달라도 된다. 타입만 일치하면 됨.
함수 오버로딩(Function Overloading)
함수 오버로딩은 하나의 함수가 여러 개의 Call Signatures를 가질 수 있게 해주는 기능이다.
함수 오버로딩 예시
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);
}
};
push('/home'); // string 버전
push({ path: '/about', state: {} }); // Config 버전다양한 오버로딩 패턴
// 매개변수 개수가 다른 오버로딩
type Calculator = {
(x: number): number;
(x: number, y: number): number;
};
const calc: Calculator = (x: number, y?: number) => {
if (y === undefined) {
return x * 2;
}
return x + y;
};다형성과 제네릭(Polymorphism & Generics)
제네릭은 타입을 파라미터화하여 재사용 가능한 컴포넌트를 만들 수 있게 해준다.
제네릭의 필요성
먼저 제네릭을 사용하지 않은 경우:
// 제네릭 없이 구현한 경우
type PrintArray = {
(arr: number[]): void;
(arr: string[]): void;
(arr: boolean[]): void;
(arr: (number | boolean)[]): void;
};이를 제네릭을 사용하여 개선하면:
// 제네릭을 사용한 경우
type PrintArray<T> = {
(arr: T[]): T;
};
const printFirst: PrintArray<any> = (arr) => arr[0];
const num = printFirst([1, 2, 3]); // number 타입 반환
const str = printFirst(["a", "b", "c"]); // string 타입 반환여러 타입 변수 사용
type KeyValuePair<K, V> = {
key: K;
value: V;
};
const pair: KeyValuePair<string, number> = {
key: "age",
value: 25
};제네릭 타입 제약 조건
// extends를 사용한 제약 조건
interface Lengthwise {
length: number;
}
function printLength<T extends Lengthwise>(arg: T): number {
return arg.length;
}
printLength("Hello"); // string has length
printLength([1, 2, 3]); // array has length
// printLength(123); // Error: number doesn't have lengthTips
1. 가능한 타입 추론 활용
// 불필요한 타입 명시
const items = genericFunction<string>(['a', 'b']);
// 타입 추론 활용
const items = genericFunction(['a', 'b']);2. 의미 있는 제네릭 타입 이름 사용
// 일반적인 컨벤션
T: Type
E: Element
K: Key
V: Value
S: State3. 함수 오버로딩 보다 유니온 타입이 더 간단할 수 있다.
// 오버로딩 사용
type StringOrNumber = {
(value: string): string;
(value: number): number;
};
// 유니온 타입 사용
type StringOrNumber = (value: string | number) => string | number;