poly는 그리스어로 많은, 다수라는 뜻입니다.
morphos는 모양, 구조라는 뜻입니다.
call signature의 타입이 많아 질 경우, generic을 사용하여 정리 가능합니다.
이는 간단히 말해서 type의 placeholder같은 역할을 한다고 볼 수 있습니다.
참고로, generic은 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법입니다.
아래와 같이 타입을 일일이 분석해서 | 연산으로 정의해도 가능하지만,
type SuperPrint = {
(arr: number[]): void;
(arr: boolean[]): void;
(arr: string[]): void;
(arr: (string | number | boolean)[]): void;
};
generic을 사용하면 코드를 조금 더 깔끔하게 작성이 가능해집니다.
type SuperPrint = {
<T>(arr: T[]): void;
};
const superprint: SuperPrint = (arr) => {
arr.forEach((element) => {
console.log(element);
});
};
superprint([1, 2, 3, 4]);
superprint([true, false, true]);
superprint(["a", "b", "c"]);
superprint([1, "b", true]);
리턴 값 또한 generic을 사용하여 표현이 가능합니다.
type SuperGeneric = {
<T>(arr: T[]): T;
};
const superGeneric: SuperGeneric = (element) => element[0];
const a = superGeneric([1, 2, 3, 4]);
const b = superGeneric([true, false, true]);
const c = superGeneric(["a", "b", "c"]);
const d = superGeneric([1, "b", true]);
그럼 여기서 의문이 들 수도 있습니다. generic을 사용하면 모든 타입을 받을 수 있게 되는데, any를 사용하는 것과 어떤 차이가 있을까요?
any를 사용하게 되면, 해당하는 모든 타입이 any로 변경되게 됩니다.
반면 generic은 받은 타입이 그대로 유지되어, 코드를 작성함에 있어 명확히 구분된 타입을 가질 수 있습니다.
다시 말해, any는 타입안전성이 떨어지게 되지만 generic은 보장됩니다.
타입을 재사용하여 클래스의 상속처럼 사용이 가능해집니다.
generic으로 하나의 타입을 생성한 뒤, 여러 타입을 넣게되면 다양한 타입을 유연하게 만들 수 있게됩니다.
type Player<E> = {
name: string;
extraInfo: E;
};
type JungExtra = {
favFood: string;
};
type JungPlayer = Player<JungExtra>;
const jung: JungPlayer = {
name: "jung",
extraInfo: {
favFood: "kukbab",
},
};