메인 콘텐츠로 건너뛰기
Deep Thought
← 목록으로
Frontend

TypeScript infer 키워드: 타입 추론의 핵심

신중선
typescripttype-inferenceconditional-typesadvanced-typesfrontend

TypeScript infer 키워드란?

TypeScript의 infer 키워드는 조건부 타입(Conditional Types)에서 특정 타입을 추론하는 데 사용되는 강력한 도구입니다. 직접 타입을 지정하는 대신, TypeScript 컴파일러가 문맥에 따라 타입을 자동으로 유추할 수 있도록 돕는 역할을 합니다.

infer는 반드시 extends 키워드와 함께 조건부 타입 안에서만 사용할 수 있습니다. 이를 통해 복잡한 타입을 분해하고, 필요한 부분만 추출하여 새로운 유틸리티 타입을 만들 수 있습니다. 특히 함수의 반환 타입, 매개변수 타입, 배열의 요소 타입 등을 추출하는 데 매우 유용합니다.

핵심 개념

1. 기본 문법과 동작 원리

infer 키워드는 조건부 타입의 extends 절에서 사용되며, 추론할 타입에 대한 플레이스홀더 역할을 합니다.

type BasicInfer<T> = T extends infer U ? U : never;

// 기본적인 함수 반환 타입 추출
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type StringReturn = GetReturnType<() => string>; // string
type NumberReturn = GetReturnType<(x: number) => number>; // number
type VoidReturn = GetReturnType<() => void>; // void

2. 함수 타입에서의 활용

함수의 매개변수와 반환 타입을 추출하는 것은 infer의 가장 일반적인 사용 사례입니다.

// 첫 번째 매개변수 타입 추출
type GetFirstParam<T> = T extends (first: infer P, ...rest: any[]) => any ? P : never;

// 모든 매개변수 타입 추출
type GetParameters<T> = T extends (...args: infer P) => any ? P : never;

// 실제 사용 예시
type ExampleFunc = (name: string, age: number, active: boolean) => User;

type FirstParam = GetFirstParam<ExampleFunc>; // string
type AllParams = GetParameters<ExampleFunc>; // [string, number, boolean]

3. 배열과 객체 타입 추론

infer는 배열의 요소 타입이나 객체의 프로퍼티 타입을 추출하는 데도 활용됩니다.

// 배열 요소 타입 추출
type ArrayElement<T> = T extends (infer U)[] ? U : never;
type StringArray = ArrayElement<string[]>; // string

// Promise 내부 타입 추출
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type ResolvedType = UnwrapPromise<Promise<User>>; // User

// 객체의 값 타입 추출
type ObjectValues<T> = T extends { [key: string]: infer V } ? V : never;
type ConfigValue = ObjectValues<{ api: string; port: number }>; // string | number

4. 고급 패턴과 실전 활용

여러 개의 infer를 조합하거나 중첩된 구조에서 타입을 추출할 수 있습니다.

// 함수 체인에서 마지막 반환 타입 추출
type GetFinalReturnType<T> = T extends (...args: any[]) => infer R
  ? R extends (...args: any[]) => infer S
    ? GetFinalReturnType<R>
    : R
  : never;

// 튜플의 첫 번째와 나머지 분리
type Head<T> = T extends [infer H, ...any[]] ? H : never;
type Tail<T> = T extends [any, ...infer T] ? T : never;

type Numbers = [1, 2, 3, 4];
type First = Head<Numbers>; // 1
type Rest = Tail<Numbers>; // [2, 3, 4]

// 재귀적 타입 변환
type Flatten<T> = T extends (infer U)[]
  ? U extends any[]
    ? Flatten<U>
    : U
  : T;

type Nested = [[string, number], [boolean]];
type Flattened = Flatten<Nested>; // string | number | boolean

정리

특징 설명 예시
사용 위치 조건부 타입의 extends 절에서만 사용 T extends infer U ? U : never
주요 용도 함수 반환/매개변수, 배열 요소, Promise 내부 타입 추출 GetReturnType<T>, ArrayElement<T>
추론 방식 TypeScript 컴파일러가 문맥에 따라 자동 추론 함수 시그니처에서 반환 타입 자동 감지
활용 범위 유틸리티 타입 제작, 타입 변환, 제네릭 제약 조건 UnwrapPromise<T>, Flatten<T>

infer 키워드는 TypeScript의 타입 시스템을 최대한 활용하여 타입 안전성을 보장하면서도 유연한 코드를 작성할 수 있게 해주는 핵심 기능입니다. 특히 라이브러리나 프레임워크에서 복잡한 타입 추론이 필요한 경우 필수적인 도구로 활용됩니다.

References