제네릭typescript
TypeScript 제네릭, 어디까지 써야 할까
✨ AI 요약
긴 글, 핵심만 먼저 — 이 글을 3줄로 정리해드려요.
조회 14
제네릭은 처음 배우면 어디에나 쓰고 싶어지고, 코드 리뷰를 몇 번 받고 나면 무서워서 못 쓴다. 내 기준은 하나다. "타입 관계를 보존해야 하는가?"
제네릭이 필요한 순간
입력 타입과 출력 타입 사이에 관계가 있을 때다.
function firstOrNull<T>(arr: T[]): T | null {
return arr[0] ?? null;
}
string[]을 넣으면 string | null이 나온다는 관계가 보존된다. 이걸 unknown이나 any로 쓰면 호출부에서 타입이 죽는다.
필요 없는 순간
관계가 없으면 유니온이나 그냥 구체 타입이 낫다.
// 과함 — T가 아무 관계도 안 만든다
function log<T extends string>(msg: T): void {}
// 충분
function log(msg: string): void {}
시그니처에 T가 한 번만 등장하면 대부분 불필요한 제네릭이다.
추론을 살리는 설계
제네릭의 가치는 호출부에서 타입 인자를 안 써도 추론되는 데 있다. 명시적으로 fn<MyType>()을 매번 써야 한다면 파라미터 설계가 추론에 불리하게 되어 있다는 신호다. 인자 위치를 조정하거나 satisfies를 활용해 추론 경로를 열어주자.
제약(extends)은 최소로
T extends { id: string }처럼 필요한 최소 형태만 요구하면 재사용성이 올라간다. 특정 인터페이스 전체를 extends로 요구하는 순간 그 함수는 사실상 그 타입 전용이 된다.
정리하면 — 관계가 있으면 제네릭, 없으면 구체 타입, 추론이 안 살면 설계 재검토. 이 세 문장이면 리뷰에서 대부분 방어된다.