May 31, 2021
function makeNumberArray(defaultValue: number, size: number): number[] {
const arr: number[] = [];
for (let i = 0; i < size; i++) {
arr.push(defaultValue);
}
return arr;
}
function makeStringArray(defaultValue: string, size: number): string[] {
const arr: string[] = [];
for (let i = 0; i < size; i++) {
arr.push(defaultValue);
}
return arr;
}
const arr1 = makeNumberArray(1, 10);
const arr2 = makeStringArray('empty', 10);
makeNumberArray
와 makeStringArray
함수가 하는 일의 로직은 거의 동일하다. 이럴 때 제네릭을 사용하면 중복 코드를 줄일 수 있다.function makeArray<T>(defaultValue: T, size: number): T[] {
const arr: T[] = [];
for (let i = 0; i < size; i++) {
arr.push(defaultValue);
}
return arr;
}
const arr1 = makeArray<number>(1, 10);
const arr2 = makeArray<string>('empty', 10);
const arr2 = makeArray<boolean>(false, 10);
makeArray<number>(1, 10);
대신 makeArray(1, 10);
와 같이 타입 정보를 지정하지 않아도 알아서 타입을 파악한다.function identity<T extends number | string>(p1: T): T {
return p1;
}
identity(1);
identity('a');
identity([]); // 컴파일 에러 발생
extends
를 함께 사용하면 타입의 종류를 제한할 수 있다.A extends B
: A
가 B
에 할당 가능해야 한다는 뜻이다.
즉, T extends number | string
: T
가 number나 string에 할당 가능해야 한다는 뜻.identity([]);
에서는 컴파일 에러가 발생한다.interface Person {
name: string;
age: number;
}
interface Korean extends Person {
liveInSeoul: boolean;
}
function swapProperty<T extends Person, K extends keyof Person>(
p1: T,
p2: T,
key: K
): void {
const temp = p1[key];
p1[key] = p2[key];
p2[key] = temp;
}
const p1: Korean = {
name: 'jessie',
age: 23,
liveInSeoul: false,
};
const p2: Korean = {
name: 'kevin',
age: 30,
liveInSeoul: true,
};
swapProperty(p1, p2, 'age');
swapProperty(p1, p2, 'job'); // 컴파일 에러 발생
swapProperty
함수에서 두 개의 제네릭 변수를 사용했는데, T extends Person
는 Person에 할당 가능한 타입으로 정의한 것이고 K extends keyof Person
는 keyof Person
에 할당 가능한 타입으로 정의한 것이다.keyof
: 인터페이스의 모든 속성 이름을 나열한 것keyof Person
이란 "name" | "age"
타입을 뜻한다.