타입스크립트 infer는 타입을 추론하는데 사용하는 키워드다. 배열 요소 타입, 함수 파라미터 타입, 함수 반환 타입 등 특정 문맥의 타입 추출이 필요할 때 infer를 활용할 수 있다.

기본 문법 : T extends infer U ? U : TU가 추론 가능한 타입이면 U 리턴, 아니면 T 리턴

infer는 타입 구현 영역(할당 연산자 우측)의 조건부 타입(extends 절)에서만 사용할 수 있으며, TS 엔진이 타입을 추론하고 변수(제네릭 타입)에 할당한다. 할당된 변수는 조건부 타입의 true 분기에서만 사용할 수 있다.

// Error! 'infer' declarations are only permitted in the 'extends' clause of a conditional type.(ts1338)
type Wrong1<T extends (infer U)[]> = T[0]; // 제약 조건 extends에 사용해서 에러
type Wrong2<T> = (infer U)[] extends T ? U : T; // extends 조건절 사용하지 않아서 에러

// Error! Cannot find name 'U'.(ts2304)
type Wrong3<T> = T extends (infer U)[] ? T : U; // false 분기에 사용해서 에러

UnpackedArray


배열 요소 타입 추출

type UnpackedArray<T> = T extends (infer U)[] ? U : T;
type T0 = string[];
type U0 = UnpackedArray<T0>; // string

UnpackedArray 유틸리티 타입 실행 흐름 via Bytefer

UnpackedArray 유틸리티 타입 실행 흐름 via Bytefer

UnpackedFn


함수 반환 타입 추출

type UnpackedFn<T> = T extends (...args: unknown[]) => infer U ? U : T;
type T1 = () => string;
type U1 = UnpackedFn<T1>; // string

함수를 오버로드했다면 마지막 호출 시그니처를 타입 추론에 사용한다. 참고로 시그니처(Signiture)는 함수나 메서드의 입력(파라미터)과 출력(반환값)에 대한 타입 정보를 의미한다.

declare function foo(x: string): number;
declare function foo(x: number): string;
declare function foo(x: string | number): string | number;

type U2 = UnpackedFn<typeof foo>; // string | number

함수를 오버로드 했을 때 시그니처 via Bytefer

함수를 오버로드 했을 때 시그니처 via Bytefer

Unpacked