TypeScript의 infer 키워드는 조건부 타입에 사용되며, 조건식이 참으로 평가될 때
사용할 수 있는 타입을 추론
하는 데 필요한 도구이다
이를 이용해 어떤 타입을 '찾아내고', 이 추론된 타입을 다른 타입과 함께 사용
할 수 있다
number extends infer U
위와 같은 경우, U타입은 number타입으로 추론(infer)이 되는 것이며
이후에 참인 경우에 대응되는 식에서 추론한 U타입을 사용할 수 있다
infer 키워드는 주로 타입 변수가 들어갈 위치에서 사용된다
예를 들어, 배열의 요소들의 타입을 추론하고 싶을 때 다음과 같이 사용한다
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type StringArray = string[];
type Element = ArrayElement<StringArray>; // 'string'
간단히 말하면 아래와 같이 정의할 수 있다.
E 가 추론 가능한 타입이면 참, 아니면 거짓
infer 키워드는 extends와 함께 사용
해야만 한다
또한 extends 중에서
조건부 타입에서도 참일 경우에만
사용이 가능하다
type ArrayElement<T> = T extends (infer E)[] ? any : E;
위의 경우처럼 조건이 false인 경우에서는 infer로 추론된 타입을 사용할 수 없다
다른 예시로 , 함수의 반환 타입을 추론하는 예시를 들어 봅시다
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
그 함수의 반환 타입
을 R (infer R) 이라고 정의하고 이 타입을 반환한다 여기서 R은 infer 키워드에 의해 추론된 함수의 반환 타입이다위의 타입을 아래와 같이 사용하는 것이다
type Func = () => number;
type Num = ReturnType<Func>; // 'number'
그 함수의 반환 타입인
number가 R 로 추론이 되어 사용되는 것이다
((
(...args: any[]) 는 나머지 매개변수를 사용해서
모든 인자를 배열로 받고 , 이 배열에는 모든 타입이 가능하다는 것을
의미합니다
예시를 들어보면
function sum(...args: number[]): number[] {
return args
}
console.log(sum(1, 2, 3)); // [1,2,3]
console.log(sum(1, 2, 3, 4, 5)); // [1,2,3,4,5]
sum 함수는 나머지 매개변수로 인해서 인자의 개수에 관계없이 모든 인자를 받을 수 있으며 , 모든 인자는 숫자형태여야 합니다
))
infer를 이용해서 프로미스의 타입을 파악하는 예시를 봅시다
TypeScript에서 Promise는 이 자체가 타입을 의미하는 것입니다
type PromiseType<T> = T extends Promise<infer U> ? U : never
type A = PromiseType<Promise<number>> // number
type B = PromiseType<Promise<string | boolean>> // string | boolean
type C = PromiseType<number> // never
type UnpackPromiseArray<P> = P extends Promise<infer K>[] ? K : any
const arr = [Promise.resolve(true)];
type ExpectedBoolean = UnpackPromiseArray<typeof arr> // boolean
알다시피 arr은 타입이 아닌 변수이므로
반드시
TS의 컴파일타임에 타입을 파악할 수 있도록 typeof와 같이 사용해야 한다
그러므로 typeof arr 은 Promise[] 이 된다