infer는 conditional type 안에서 다른 타입으로부터 어떤 타입을 *포착(추출)*하여, 이후 사용할 수 있는 새 타입 변수에 담는 데 쓰입니다. 타입을 위한 패턴 매칭입니다.
ts
// 배열의 요소 타입 추출
type ElementOf<T> = T extends (infer U)[] ? U : never;
type A = ElementOf<string[]>; // string
B = <[]>;
infer는 conditional type 안에서 다른 타입으로부터 어떤 타입을 *포착(추출)*하여, 이후 사용할 수 있는 새 타입 변수에 담는 데 쓰입니다. 타입을 위한 패턴 매칭입니다.
// 배열의 요소 타입 추출
type ElementOf<T> = T extends (infer U)[] ? U : never;
type A = ElementOf<string[]>; // string
B = <[]>;
이렇게 읽으세요: "만약 T가 패턴 U[]와 일치하면, U를 요소 타입이 무엇이든 그것에 바인딩하고 반환하라." infer U는 컴파일러가 매칭으로 채우는 자리표시자를 선언합니다.
// Promise가 resolve하는 타입
type Awaited2<T> = T extends Promise<infer R> ? R : T;
type R = Awaited2<Promise<User>>; // User
// 함수의 반환 타입 (ReturnType이 이렇게 만들어짐)
type MyReturn<T> = T extends (...args: any[]) => infer R ? R : never;
type X = MyReturn<() => number>; // number
// 함수의 첫 번째 매개변수
type FirstArg<T> = T extends (a: infer A, ...rest: any[]) => any ? A : never;
type UnwrapBoth<T> =
T extends Promise<infer U> ? UnwrapBoth<U> : // 중첩 promise를 풀기 위해 재귀
T extends (infer E)[] ? E : T;
하나의 패턴에서 여러 infer를 사용할 수 있고 재귀도 가능합니다.
infer는 ReturnType, Parameters, Awaited, InstanceType 같은 내장 타입의 엔진이며, 페처로부터 응답 타입을 파생하거나 컴포넌트로부터 props를 파생하는 라이브러리 마법의 배후입니다.
타입 코드가 복잡한 타입을 "열어" 내부 조각들을 꺼낼 수 있게 해줍니다 — 다른 타입에 적응하는 타입을 작성하는 가장 강력한 도구입니다.