"Overload 는 한 함수가 사실 같은 모자 쓴 여러 함수일 때 쓰는 거."
Overload 의 모양
함수 overload 는 단일 함수에 여러 call signature 주는 방법. 먼저 overload signature 들 (공개 contract) 쓰고, 그다음 다 union 으로 받는 단일 구현 signature. 구현 signature 는 직접 호출 안 됨 — overload signature 만 호출 가능.
function format(value: number): string;
function format(value: Date): string;
function format(value: number | Date): string {
// 구현이 둘 다 처리
return value instanceof Date ? value.toISOString() : value.toFixed(2);
}
Caller 가 2개 구별된 signature 봐: `number` 나 `Date` 전달, `string` 받음. Compiler 가 호출을 구현으로 라우팅. 구현이 runtime 체크로 두 입력 처리.
Overload 가 옳은 tool 일 때
함수가 진짜로 여러, 구별된 call 모양 가지고 AND 단일 signature (union 타입, generic, conditional 타입) 가 그 관계 깔끔히 표현 못 할 때 overload 써.
반례 — 단일 signature 이기는 자리들:
- 같은 parameter, 여러 타입:
function format(value: number | Date): string— union, overload 불필요. - 타입 의존 return:
function wrap<T>(x: T): { value: T }— generic, overload 불필요. - 입력 기반 조건부 return:
function f<T>(x: T): T extends string ? number : string— conditional 타입, overload 불필요.
Overload 가 빛나는 곳: Call 모양들이 다른 parameter 개수 가질 때, 또는 구별된 call 모양들이 IDE hover 에 구별된 문서 필요할 때.
구현-signature 함정
구현 signature 는 private — caller 가 볼 수 없음. 근데 모든 overload signature 의 union 을 받아야 함. Overload 4개 쓰고 narrow 한 구현 쓰면 compiler 불평.
더 나빠: 구현 signature 는 호환성 체크되지만 public 타입의 일부 아님. any 받아도 caller 는 public signature 만 사용 가능. 이게 "내 구현이 any 받으니까 이 호출 작동해" 가정하는 developer 잡아.