반응형
infer 키워드
조건부 타입의 마지막 특성으로 조건의 일부를 제네릭 타입으로 선언할 수 있는 기능을 꼽을 수 있습니다.
참고로 지금까진 제네릭 타입 매개변수를 선언하는 방법으로 꺾쇠괄호(<T>)를 이용하는 방법 한 가지만 배웠습니다.
조건부 타입에선 제네릭 타입을 인라인으로 선언하는 전용 문법을 제공합니다.
바로 infer 키워드입니다.
배열의 요소 타입을 얻는 ElementType이라는 조건부 타입을 정의해 봅시다.
type ElementType<T> = T extends unknown[] ? T[number] : T
type A = ElementType<number[]> // type A = number
infer를 이용하면 이 코드를 다음처럼 다시 구현할 수 있습니다.
type ElementType2<T> = T extends (infer U)[] ? U : T
type A = ElementType2<number[]> // type A = number
위의 간단한 예에서 ElementType은 ElementType2와 같습니다.
infer문으로 새로운 타입 변수 U를 어떻게 선언하는지 확인해 봅시다.
TypeScript는 ElementType2에 어떤 T를 전달했느냐를 보고 U의 타입을 추론합니다.
그리고 U를 T와 함께 미리 선언하지 않고 인라인으로 선언한 이유도 확인합니다.
다음처럼 미리 선언한다면 어떤 일이 일어날까요?
type ElementUgly<T, U> = T extends U[] ? U : T
type C = ElementUgly<number[]> // 'ElementUgly' 제네릭 형식에 2 형식 인수가 필요합니다.ts(2314)
ElementUgly는 T와 U 두 개의 제네릭 타입을 정의하므로 인스턴스화할 때 둘 모두를 인수로 전달해야 합니다.
하지만 그렇게 되면 애초에 ElementUgly 자체를 정의할 필요가 없어집니다.
ElementUgly가 타입을 스스로 추론할 수 있게 하려면 호출자가 U의 타입을 알아내야 하기 때문입니다.
더 복잡한 예를 확인해 보겠습니다.
type FirstArg<F> = F extends (a: any, b: infer B) => any ? B : never
// Array.slice의 타입 얻기!
type F = typeof Array['prototype']['slice']
type A = FirstArg<F> // type A = number | undefined
[].slice의 두 번째 인수는 number | undefined이고, 이 사실을 컴파일 타임에 알 수 있습니다.
반응형
'👶 TypeScript' 카테고리의 다른 글
탈출구 - 타입 어서션 (0) | 2023.01.21 |
---|---|
조건부 타입 - 내장 조건부 타입들 (0) | 2023.01.21 |
조건부 타입 - 분배적 조건부 (0) | 2023.01.21 |
조건부 타입 (0) | 2023.01.21 |
고급 함수 타입들 - 사용자 정의 타입 안전 장치 (0) | 2023.01.20 |