TypeScript제네릭과 타입 조작

conditional types와 infer

타입 수준에서 분기를 만들고 내부 구조에서 정보를 추출하는 conditional types와 `infer`의 핵심을 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

ts
type Flatten<T> = T extends Array<infer Item> ? Item : T;

type A = Flatten<string[]>; // string
type B = Flatten<number>;   // number

설명

  • conditional type은 JavaScript의 삼항 연산자와 비슷한 모양으로 타입 수준 분기를 만드는 문법입니다. 즉 "이 타입이 어떤 구조라면 A, 아니면 B"를 표현할 수 있습니다.
  • 이 문법의 진짜 힘은 infer와 만날 때 나옵니다. infer는 비교 대상 구조 안에서 일부 타입 정보를 끄집어내 새 이름으로 바인딩하게 해 줍니다.
  • 예를 들어 배열 요소 타입, 함수 반환 타입, Promise 안쪽 값 타입을 직접 인덱싱하지 않고 "패턴에서 추론"할 수 있습니다. 그래서 타입 조작이 훨씬 선언적이 됩니다.
  • ReturnType, Awaited 같은 내장 유틸리티 타입도 이런 사고방식으로 이해할 수 있습니다. 결국 conditional type은 "타입의 구조를 보고 분기하고, 필요한 조각을 추출한다"는 도구입니다.
  • 실무에서는 API helper, 라이브러리 타입 정의, 함수 시그니처 추론, 프레임워크 유틸리티 타입을 읽을 때 이 개념이 계속 등장합니다.

빠른 정리

표현의미
T extends U ? A : BT가 U 구조를 만족하면 A, 아니면 B
infer X비교 구조 안에서 타입 일부를 추출
잘 맞는 사용처반환 타입 추출, 배열 요소 타입 추출, Promise 언랩
장점타입 구조 기반의 재사용 가능한 분기 로직 작성
난이도강력하지만 읽기 어려워지기 쉬움

주의할 점

conditional type은 조금만 중첩돼도 난해해질 수 있습니다. "이 타입이 무엇을 테스트하고 어떤 정보를 꺼내는가"를 주석 없이 읽기 어려워진다면 이름을 더 잘게 나누는 편이 좋습니다.

참고 링크

1 sources