
타입스크립트 infer 키워드 완벽 정복 가이드
타입스크립트에서 infer 키워드는 조건부 타입 안에서 타입을 추론할 때 사용됩니다.
복잡한 타입을 다룰을 때 특히 유용하며, 타입을 추출하거나 변환할 수 있게 해준죠.
1. 기본 사용법
infer 키워드는 조건부 타입 안에서만 사용할 수 있으며, 보통 제네릭과 extends 키워드와 함께 사용됩니다. 문법은 다음과 같습니다.
type Moment<T> = T extends infer U ? U : never;
여기서 T extends infer U는 T 타입을 추론하여 U에 할당하려고 시도한다는 의미입니다.
타입 추론이 성공하면 U는 추론된 타입이 됩니다.
다양한 타입을 추론하는 데 사용할 수 있습니다. 몇 가지 예시를 들어보겠습니다.
type Moment<T> = T extends infer U ? U : never;
type StringType = Moment<string>; // string
type NumberType = Moment<number>; // number
type UnionType = Moment<string | number>; // string | number
interface User {
name: string;
age: number;
}
type UserType = Moment<User>; // User
이 예시에서 Moment는 기본적으로 변환이나 처리 없이 타입 T를 반환합니다.
이는 주로 조건부 타입과 타입 추론의 기본 사용법을 보여주기 위한 것입니다.
2. 일반적인 예시
함수의 반환 타입 추출하기
함수 타입이 있고 그 반환 타입을 추출하고 싶다고 가정해봅시다.
다음과 같이 할 수 있습니다.
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type ExampleFunction = (x: number, y: string) => boolean;
type ReturnTypeOfExampleFunction = GetReturnType<ExampleFunction>; // boolean
위 코드에서:
T extends (...args: any[]) => infer R: T가 함수 타입인지 확인합니다.(...args: any[])는 함수가 어떤 수의 인수를 받아들일 수 있음을 의미합니다.infer R: T가 함수 타입이면 infer R은 함수의 반환 타입을 추론하여 타입 변수 R에 할당합니다.? R : never: T가 함수 타입이면 추론된 반환 타입 R을 반환하고, 그렇지 않으면 never를 반환합니다.
배열의 요소 타입 추출하기
infer를 사용하여 배열의 요소 타입도 추출할 수 있습니다.
type GetArrayElementType<T> = T extends (infer U)[] ? U : never;
type Moment = string[];
type Example1Array = Array<string>;
type ElementTypeOfExampleArray = GetArrayElementType<Moment>; // string
type ElementTypeOfExample1Array = GetArrayElementType<Example1Array>; // string
여기서 T extends (infer U)[]를 사용하여 배열의 요소 타입 U를 추론합니다.
T가 string[]이므로 U는 string이 됩니다.
중요 참고: infer 선언은 조건부 타입의 extends 절 안에서만 허용되며, infer로 선언된 타입 변수는 true 분기 안에서만 사용할 수 있습니다.
3. 고급 예시
프로미스의 값 타입 추출하기
프로미스 타입이 있으면 그 해결된 값 타입을 추출할 수 있습니다.
type GetPromiseValueType<T> = T extends Promise<infer U> ? U : never;
// 예시
type ExamplePromise = Promise<number>;
type ValueTypeOfExamplePromise = GetPromiseValueType<ExamplePromise>; // number
위 코드에서:
T extends Promise<infer U>: T가 프로미스 타입인지 확인합니다.infer U: T가 프로미스 타입이면 infer U는 프로미스의 해결된 값 타입을 추론하여 U에 할당합니다.? U : never: T가 프로미스 타입이면 추론된 값 타입 U를 반환하고, 그렇지 않으면 never를 반환합니다.
함수의 매개변수 타입 추출하기
때때로 함수의 매개변수 타입을 얻어야 할 때가 있습니다.
infer를 사용하여 이를 달성할 수 있습니다.
type GetParameters<T> = T extends (...args: infer P) => any ? P : never;
type ExampleFunction = (a: number, b: string) => void;
type Params = GetParameters<ExampleFunction>; // [number, string]
위 코드에서:
T extends (...args: infer P) => any: T가 함수 타입인지 확인합니다.infer P: T가 함수 타입이면 infer P는 함수의 매개변수 타입을 추론하여 P에 할당합니다.? P : never: T가 함수 타입이면 추론된 매개변수 타입 P를 반환하고, 그렇지 않으면 never를 반환합니다.
생성자 매개변수 타입 추출하기
infer를 사용하여 클래스 생성자의 매개변수 타입도 추출할 수 있습니다.
type ConstructorParameters<T> = T extends new (...args: infer P) => any ? P : never;
class ExampleClass {
constructor(public a: number, public b: string) {}
}
type Params = ConstructorParameters<typeof ExampleClass>; // [number, string]
4. 조건부 타입에서의 복잡한 추론
조건부 타입 안에서 복잡한 추론 로직을 사용해야 할 때가 있습니다.
type IsArray<T> = T extends (infer U)[] ? U : never;
type IsFunction<T> = T extends (...args: any[]) => infer R ? R : never;
type ExtractType<T> = T extends any[]
? IsArray<T>
: T extends (...args: any[]) => any
? IsFunction<T>
: T;
// 예시
type ArrayType = ExtractType<string[]>; // string
type FunctionReturnType = ExtractType<() => number>; // number
type DefaultType = ExtractType<boolean>; // boolean
위 코드에서:
T extends any[] ? IsArray<T>: T가 배열 타입이면 IsArray를 반환하여 배열의 요소 타입을 추출합니다.T extends (...args: any[]) => any ? IsFunction<T>: T가 함수 타입이면 IsFunction을 반환하여 함수의 반환 타입을 추출합니다.T: T가 배열 타입도 함수 타입도 아니면 T 자체를 반환합니다.
요약
타입스크립트에서 infer 키워드는 조건부 타입 안에서 다른 타입으로부터 새로운 타입 변수를 추론할 때 사용됩니다.
타입 검사 중에 특정 하위 타입이나 속성을 추출하고 활용할 수 있게 해주어 타입스크립트의 타입 시스템의 표현력과 유연성을 향상시킵니다.
간단히 말해, infer는 복잡한 타입에서 원하는 부분을 자동으로 추출하는 데 도움을 줍니다.
'Javascript' 카테고리의 다른 글
| 자바스크립트 샌드박스 완벽 파헤치기: 안전한 코드 실행 환경 만들기 (0) | 2025.05.05 |
|---|---|
| 노드JS에서 멀티스레딩 완벽 정복! 성능 향상의 비밀 풀기 (1) | 2025.04.28 |
| Node.js 성능의 비밀! libuv와 함께 CPU/IO 바운드 완벽 정복 가이드 (1) | 2025.04.26 |
| CSS 로딩이 DOM 파싱과 렌더링에 미치는 영향 (1) | 2025.04.25 |
| 타입스크립트 type vs interface: 언제 뭘 써야 할지 헷갈린다면? (완벽 정리) (0) | 2025.04.12 |