infer 완전정복 3편: 활용편 (고급 단계)
1. 중첩된 Promise에서 최종 타입 추출 – DeepUnwrap<T>
type DeepUnwrap<T> = T extends Promise<infer U> ? DeepUnwrap<U> : T;
type A = DeepUnwrap<Promise<string>>;
type B = DeepUnwrap<Promise<Promise<number>>>;
type C = DeepUnwrap<Promise<Promise<Promise<boolean>>>>;
- 핵심:
infer를 재귀적으로 적용해서 가장 안쪽 타입까지 파고든다.
2. 중첩 배열 타입을 평탄화 – Flatten<T>
type Flatten<T> = T extends (infer U)[]
? U extends any[]
? Flatten<U>
: U
: T;
type A = Flatten<string[][][]>;
type B = Flatten<number[][]>;
type C = Flatten<boolean[]>;
type D = Flatten<string>;
- 중첩 배열을 재귀적으로 풀어서 최종 요소 타입을 구한다.
Flatten<T>는 실제 실무에서도 자주 등장하는 고급 유틸리티이다.
3. 함수 전체 시그니처 분해 – FunctionParts<T>
type FunctionParts<T> =
T extends (...args: infer A) => infer R
? { args: A; return: R }
: never;
type F = (x: number, y: string) => boolean;
type R = FunctionParts<F>;
infer를 한 번에 매개변수와 반환 타입 모두 추출할 수 있다는 예시.
- 실무에서는
FnSignature 타입 추출에 유용하다.
4. 생성자 함수에서 인스턴스 타입 추출 – InstanceType<T>
type MyInstanceType<T> = T extends new (...args: any[]) => infer R ? R : never;
class User {
constructor(public name: string) {}
}
type A = MyInstanceType<typeof User>;
new 키워드를 사용할 수 있다는 게 포인트!
- 생성자 함수에서 만들어지는 인스턴스 타입을 추출할 수 있다.
5. 조건을 만족하는 프로퍼티만 추출 – PickByValue<T, V>
type PickByValue<T, V> = {
[K in keyof T as T[K] extends V ? K : never]: T[K]
};
type Example = {
id: number;
name: string;
age: number;
isAdmin: boolean;
};
type OnlyNumbers = PickByValue<Example, number>;
- K in keyof T
- T라는 객체 타입의 모든 키(key)를 K라는 이름으로 하나씩 돌린다는 뜻.
- 예: T = { id: number; name: string; } 라면 → K는 "id" 또는 "name"이 된다.
- as (T[K] extends V ? K : never)
- T[K] 가 주어진 V의 서브타입이면 K , 아니면 never
- 주어진 V 타입인 키만 남기고 그외의 타입을 가지는 키는 제외하는 구조
infer 없이 조건부 타입을 조합한 고급 매핑.
- 타입 유틸리티에서 조건에 맞는 프로퍼티만 뽑을 때 자주 사용된다.
6. 특정 프로퍼티의 타입 바꾸기 – ReplaceValueType<T, From, To>
type ReplaceValueType<T, From, To> = {
[K in keyof T]: T[K] extends From ? To : T[K];
};
type Original = {
id: number;
name: string;
active: boolean;
};
type Updated = ReplaceValueType<Original, boolean, string>;
- K in keyof T
- T라는 객체 타입의 모든 키(key)를 K라는 이름으로 하나씩 돌린다는 뜻.
- T[K] extends From ? To : T[K]
- 현재 프로퍼티의 타입이 From과 호환된다면 그 타입을 To로 바꾸고 아니면 원래 타입 유지
- 타입을 조건부로 교체하거나 그대로 유지
- 객체 타입 T에서, 특정 값 타입(From)을 가진 프로퍼티만 찾아서 그 값의 타입을 To로 변환
마무리 요약
| 유틸리티 이름 | 기능 |
|---|
DeepUnwrap<T> | 중첩 Promise 구조 해제 |
Flatten<T> | 다차원 배열 타입 해제 |
FunctionParts<T> | 함수 시그니처 분해 |
MyInstanceType<T> | 생성자 인스턴스 타입 추출 |
PickByValue<T, V> | 특정 타입만 추출한 객체 |
ReplaceValueType<T> | 특정 타입을 다른 타입으로 변경 |