TypeScript에서 infer 키워드 이해하기
Daniel Hayes
Full-Stack Engineer · Leapcell

TypeScript의 infer
키워드는 조건부 타입에서 타입을 추론하는 데 사용됩니다. 이는 복잡한 타입을 다룰 때 특히 유용하며, 타입을 추출하거나 변환할 수 있게 해 줍니다.
기본 사용법
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>
는 기본적으로 변환이나 처리 없이 타입 T
를 반환합니다. 이는 주로 조건부 타입과 타입 추론의 기본 사용법을 보여주기 위한 것입니다.
일반적인 예
함수의 반환 타입 추출
함수 타입이 있고 반환 타입을 추출하고 싶다고 가정해 보겠습니다. 다음과 같이 할 수 있습니다:
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
이 됩니다.
string[] extends (infer U)[ ]
infer
선언은 조건부 타입의 extends
절 내에서만 허용되며, infer
로 선언된 타입 변수는 true 분기 내에서만 사용할 수 있다는 점에 유의해야 합니다.
고급 예
Promise의 값 타입 추출
Promise
타입이 있는 경우, 그 resolved된 값 타입을 추출할 수 있습니다.
type GetPromiseValueType<T> = T extends Promise<infer U> ? U : never; // Example type ExamplePromise = Promise<number>; type ValueTypeOfExamplePromise = GetPromiseValueType<ExamplePromise>; // number
위 코드에서:
T extends Promise<infer U>
: 이는T
가Promise
타입인지 확인합니다.infer U
:T
가Promise
타입이면infer U
는Promise
의 resolved된 값 타입을 추론하여U
에 할당합니다.? U : never
:T
가Promise
타입이면 추론된 값 타입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]
조건부 타입에서의 복잡한 추론
조건부 타입 내에서 복잡한 추론 로직을 사용해야 한다고 가정해 보겠습니다.
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; // Example type ArrayType = ExtractType<string[]>; // string type FunctionReturnType = ExtractType<() => number>; // number type DefaultType = ExtractType<boolean>; // boolean
이 코드에서:
type ExtractType<T> = T extends any[] ? IsArray<T> : T extends (...args: any[]) => any ? IsFunction<T> : T;
T extends any[] ? IsArray<T>
:T
가 배열 타입이면 배열의 요소 타입을 추출하는IsArray
를 반환합니다.T extends (...args: any[]) => any ? IsFunction<T>
:T
가 함수 타입이면 함수의 반환 타입을 추출하는IsFunction
을 반환합니다.T
:T
가 배열 타입도 함수 타입도 아니면T
자체를 반환합니다.
요약
infer
키워드는 조건부 타입에서 다른 타입으로부터 새로운 타입 변수를 추론하는 데 사용됩니다. 타입 검사 중에 특정 서브타입 또는 속성을 추출하고 활용할 수 있게 해주어 TypeScript의 타입 시스템의 표현력과 유연성을 향상시킵니다. 간단히 말해서, infer
는 복잡한 타입에서 원하는 부분을 자동으로 추출하는 데 도움이 됩니다.
저희는 Node.js 프로젝트 호스팅을 위한 최고의 선택, Leapcell입니다.
Leapcell은 웹 호스팅, 비동기 작업 및 Redis를 위한 차세대 서버리스 플랫폼입니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발하세요.
무제한 프로젝트를 무료로 배포하세요
- 사용량에 대해서만 비용을 지불하세요. 요청이 없으면 요금이 부과되지 않습니다.
타의 추종을 불허하는 비용 효율성
- 유휴 요금 없이 사용량에 따라 지불하세요.
- 예: $25로 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리할 수 있는 자동 확장.
- 운영 오버헤드가 없으므로 구축에만 집중하세요.
설명서에서 자세히 알아보세요!
X에서 팔로우하세요: @LeapcellHQ