반응형
한정된 다형성으로 인수의 개수 정의하기
가변 인수 함수 (= 임의의 개수의 인수를 받는 함수)에서도 한정된 다형성을 사용할 수 있습니다.
예를 들어 JavaScript의 내장 call 함수를 직접 구현하면, 아래처럼 정의하고 사용할 수 있습니다.
call은 함수 하나와 임의 개수의 인수를 받아서 이 인수들을 함수에 건네 호출하는 함수입니다.
function call(
f: (...args: unknown[]) => unknown,
...args: unknown[]
): unknown {
return f(...args)
}
function fill(length: number, value: string): string[] {
return Array.from({length}, () => value)
}
call(fill, 10, 'a') // 'a' 10개를 갖는 배열로 평가
unknown을 채워보겠습니다.
표현하려는 제한은 다음과 같습니다.
- f는 T타입의 인수 몇 개 받아서 R 타입을 반환하는 함수입니다. 인수가 몇 개인지는 미리 알 수 없습니다.
- call은 f 한 개와 T 몇 개를 인수로 받으며, 인수로 받은 T들을 f가 다시 인수로 받습니다. 마찬가지로 인수가 몇 개인지 미리 알 수 없습니다.
- call은 f의 반환 타입과 같은 R 타입을 반환합니다.
따라서 인수 배열 타입 T와 임의의 반환 값 R, 이렇게 두 가지의 타입 매개변수가 필요합니다.
이 두 타입을 채워보겠습니다.
function call<T extends unknown[], R>( // ①
f: (...args: T) => R, // ②
...args: T // ③
): R { // ④
return f(...args)
}
① call은 가변 인수 함수로 T와 R 두 개의 타입 매개변수를 받습니다. T는 unknown[]의 서브타입, 즉 어떤 타입의 배열 또는 튜플입니다.
② call의 첫 번째 인수는 함수 f입니다. f 또한 가변 인수 함수로, args와 같은 타입의 인수를 받습니다. 따라서 args 타입이 무엇이든 f 인수의 타입도 똑같습니다.
③ f 함수 외에도, call은 임의의 개수의 매개변수 ...args를 추가로 받습니다. args는 나머지 매개변수, 즉 임의의 개수의 인수를 받을 수 있는 매개변수입니다. args의 타입은 T이며 T는 배열 타입이어야 하므로 TypeScript는 args용으로 전달한 인수를 보고 T에 걸맞은 튜플 타입을 추론합니다.
④ call은 R 타입의 값을 반환합니다.
이제 call을 호출하면 TypeScript는 반환 타입이 무엇인지 알 수 있고, 인수의 개수가 잘못되었다면 에러를 발생시킵니다.
function call<T extends unknown[], R>( // ①
f: (...args: T) => R, // ②
...args: T // ③
): R { // ④
return f(...args)
}
function fill(length: number, value: string): string[] {
return Array.from({length}, () => value)
}
let a = call(fill, 10, 'a') // string[]
let b = call(fill, 10) // 3개의 인수가 필요한데 2개를 가져왔습니다.ts(2554)
let c = call(fill, 10, 'a', 'z') // 3개의 인수가 필요한데 4개를 가져왔습니다.ts(2554)
반응형
'👶 TypeScript' 카테고리의 다른 글
타입 주도 개발 (0) | 2023.01.14 |
---|---|
제네릭 타입 기본값 (0) | 2023.01.14 |
여러 제한을 적용한 한정된 다형성 (0) | 2023.01.13 |
한정된 다형성 (0) | 2023.01.13 |
제네릭 타입 별칭 (0) | 2023.01.13 |