Typescript Infer 3편 : 활용(고급)

프디·2025년 4월 13일

Typescript infer

목록 보기
3/5

infer 완전정복 3편: 활용편 (고급 단계)

1. 중첩된 Promise에서 최종 타입 추출 – DeepUnwrap<T>

type DeepUnwrap<T> = T extends Promise<infer U> ? DeepUnwrap<U> : T;

type A = DeepUnwrap<Promise<string>>;              // string
type B = DeepUnwrap<Promise<Promise<number>>>;     // number
type C = DeepUnwrap<Promise<Promise<Promise<boolean>>>>;  // boolean
  • 핵심: infer재귀적으로 적용해서 가장 안쪽 타입까지 파고든다.

2. 중첩 배열 타입을 평탄화 – Flatten<T>

type Flatten<T> = T extends (infer U)[]
  ? U extends any[]
    ? Flatten<U>
    : U
  : T;

type A = Flatten<string[][][]>; // string
type B = Flatten<number[][]>;   // number
type C = Flatten<boolean[]>;    // boolean
type D = Flatten<string>;       // 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>;
// { args: [number, string]; return: boolean }
  • 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>;  
// 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>;
// { id: number; age: number }
  1. K in keyof T
    • T라는 객체 타입의 모든 키(key)를 K라는 이름으로 하나씩 돌린다는 뜻.
    • 예: T = { id: number; name: string; } 라면 → K는 "id" 또는 "name"이 된다.
  2. 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>;
// {
//  id: number;         // number는 boolean 아님 → 유지
//  name: string;       // string은 boolean 아님 → 유지
//  active: string;     // boolean → ✅ string으로 변경됨!
//}
  1. K in keyof T
    • T라는 객체 타입의 모든 키(key)를 K라는 이름으로 하나씩 돌린다는 뜻.
  2. 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>특정 타입을 다른 타입으로 변경

profile
프론트엔드개발자인디

0개의 댓글