조건부 타입 (Conditional Types)
- 어떤 타입이 다른 타입에 할당 가능한지에 따라 타입을 결정
- 입력값의 타입에 따라 결과 타입이 달라지는 복잡한 라이브러리 함수를 만들 때 사용
- 삼항 연산자와 유사한 문법을 사용
- 기본 문법**:**
T extends U ? X : Y
T가 U에 할당 가능하다면 X 타입이 되고, 아니면 Y 타입
type IsString<T> = T extends string ? true : false;
type T1 = IsString<string>;
type T2 = IsString<number>;
분산적인 조건부 타입 (Distributive Conditional Types)
- 제네릭 타입에 유니온 타입을 전달하면, 유니온의 각 요소를 하나씩 떼어내어 조건부를 적용한 뒤 다시 합치는 동작
- 유니온 타입에서 내가 원하는 타입만 골라내거나, 필요 없는 타입을 버릴 때 사용
- 작동 원리:
(A | B) extends U ? X : Y → (A extends U ? X : Y) | (B extends U ? X : Y)
// -- 특정 타입을 유니온에서 제거하는 예제 --
type Exclude<T, U> = T extends U ? never : T;
type Result = Exclude<string | number | boolean, number>;
// (string | number | boolean) extends U ? never : T;
// (string extends U ? never : T;) | (number extends U ? never : T;) | (boolean extends U ? never : T;)
// string extends number ? never : string; // string
// number extends number ? never : number; // never
// boolean extends number ? never : boolean; // boolean
// string | boolean
infer 키워드
- 조건부 타입의
extends 절에서 특정 타입을 추론(Inference)하여 변수처럼 추출해낼 때 사용
- 함수의 리턴 타입, 배열의 요소 타입 등을 추출하여 변수 타입으로 사용 할 때 유용
// -- 리턴 타입을 추출하는 유틸리티 --
type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function getName() { return '홍길동'; }
type GetNameReturnType = GetReturnType<typeof getName>;
// -- 배열 요소의 타입 추출 --
type UnpackArray<T> = T extends (infer U)[] ? U : never;
type strArr = UnpackArray<string[]>;
type numArr = UnpackArray<number[]>;
type sArr = UnpackArray<'asdasd'>;