2025. 6. 12. 13:29ㆍ카테고리 없음
타입스크립트 조건부 타입 (Conditional Types)
조건부 타입은 삼항 연산자와 비슷한 문법으로 타입을 조건에 따라 다르게 정의할 수 있는 기능이다. 다음과 같은 형태를 가진다.
T extends U ? X : Y
위 표현은 "T가 U에 할당 가능하면 X, 그렇지 않으면 Y"라는 의미이다.
예제: 기본 조건부 타입
type IsString<T> = T extends string ? "Yes" : "No";
type A = IsString<string>; // "Yes"
type B = IsString<number>; // "No"
이 예제에서 IsString 타입은 주어진 타입이 문자열이면 "Yes"를, 아니면 "No"를 반환한다.
분산적인 조건부 타입 (Distributive Conditional Types)
유니언 타입에 조건부 타입을 적용하면, 타입스크립트는 유니언의 각 멤버에 조건부 타입을 개별적으로 적용하여 결과를 다시 유니언으로 만든다. 이를 분산적인 조건부 타입이라 한다.
예제: 분산 조건부 타입
type ToArray<T> = T extends any ? T[] : never;
type A = ToArray<string>; // string[]
type B = ToArray<string | number>; // string[] | number[]
ToArray 타입에 string | number를 전달하면, 조건부 타입이 각각 string extends any, number extends any로 평가되어 string[] | number[]가 된다.
분산을 막는 방법
분산적인 조건부 타입의 동작을 막고 싶다면 타입을 대괄호로 감싸서 단일 요소로 처리하면 된다.
type ToArrayNoDistrib<T> = [T] extends [any] ? T[] : never;
type A = ToArrayNoDistrib<string | number>; // (string | number)[]
이렇게 하면 string | number 전체를 하나의 타입으로 보고 배열로 감싸므로 결과는 (string | number)[]가 된다.
타입 제거하기
T 에 모든 타입을 대입하고 U 타입만 제거하기
type RemoveType<T,U> = T extends U ? never : T
type A = RemoveType< number | string | boolean, string >
< 코드 실행 순서 >
1 단계 : 아래의 타입을 T 에 각 각 대입을 한다.
2 단계
- 첫번째의 경우 numbeer 는 string 의 extends 가 아니기 때문에 false 가 되어서 number
- 두번째의 경우 string 은 string의 extends 기 때문에 true 가 되어서 never 가 됨
- 세번째의 경우 boolean 은 string의 extends 가 아니기 때문에 false 가 되어서 boolean 이 된다.
RemoveType< number , string > // number
RemoveType< string , string > // never
RemoveType< boolean, string > // boolean
결과
type A = number | never | boolean
여기서 never 는 number 타입에도 대입이 되고 boolean 에도 대입이 되는 공집합이라서 사라지고
아래와 같이 된다.
type A = number | boolean

타입 추출하기
T 에 모든 타입을 대입하고 U 타입만 추출하기
type RemoveType<T,U> = T extends U ? T : never // T와 never 의 순서만 바꾸면 된다.
type A = RemoveType< number | string | boolean, string >

요약
- 조건부 타입은 타입을 조건에 따라 다르게 지정할 수 있는 기능이다.
- 유니언 타입에 조건부 타입을 적용하면 자동으로 분산된다.
- 분산을 막고 싶다면
[T] extends [U]형식처럼 묶어주면 된다.