인자 확인
호출에 들어온 타입과 개수를 선언된 목록과 비교한다.
함수 오버로딩은 여러 호출 형태를 문서처럼 드러내면서도 실제 코드는 하나만 둔다. 그래서 선택된 시그니처와 구현 시그니처의 포괄성이 함께 맞아야 한다.
호출에 들어온 타입과 개수를 선언된 목록과 비교한다.
더 구체적인 오버로드가 앞에 있으면 의도한 반환 타입을 얻는다.
실행되는 함수는 마지막 구현 시그니처 하나뿐이다.
본문에서 typeof, Array.isArray 같은 검사로 분기한다.
getLength("abc")
input: string
number
구현 함수 안에서 문자열 분기
getLength(["a", "b"])
input: string[]
number
같은 구현 함수 안에서 배열 분기
호출자는 선언된 오버로드 목록만 보고 반환 타입을 기대한다.
위에서부터 맞는 선언을 찾고, 가장 알맞은 호출 타입을 고른다.
런타임에는 구현 하나만 호출되고, 내부 타입 가드가 실제 분기를 맡는다.
function getLength(input: string): number;
호출자가 문자열을 넘기면 반환 타입은 number로 바로 확정된다.
function getLength(input: string[]): number;
배열 호출도 별도 사용법으로 드러나 문서 역할을 한다.
function getLength(
input: string | string[]
): number {
return input.length;
}
구현 시그니처는 호출자가 직접 보는 타입이 아니라, 선언한 모든 오버로드를 실제로 처리하기 위한 내부 타입이다.
`parse(string): number`, `parse(number): string`처럼 호출 형태와 결과 타입의 대응이 중요하면 오버로드가 읽기 쉽다.
내부에서 타입만 좁히면 되고 반환 타입이 하나로 설명되면 `string | number`가 더 간단하다.
리터럴 타입이나 좁은 형태를 넓은 타입보다 먼저 선언한다.
구현 매개변수는 모든 오버로드 인자를 받을 수 있어야 한다.
호출부는 구현 시그니처가 아니라 오버로드 목록만 보고 검사된다.