타입스크립트 - 컨디셔널 타입
컨디셔널 타입
조건에 따라 다른 타입이 되는 타입
1
2
3
특정 타입 extends 다른 타입
? 참일 때 타입
: 거짓일 때 타입
1
2
3
4
5
type A1 = string;
type B1 = A1 extends string ? number : boolean; // type B1 = number
type A2 = number;
type B2 = A2 extends string ? number : boolean; // type B2 = boolean
- A1이 string이기때문에 B1은 조건문이 참이다. 따라 B1은 number 타입이 된다.
- A2이 number이기때문에 B2은 조건문이 거짓이다. 따라 B2는 boolean 타입이 된다.
컨디셔널 타입은 타입 검사를 위해서도 많이 사용한다.
1
2
type Result = "hi" extends string ? true : false; // type Result = true
type Result2 = [1] extends [string] ? true : false; // type Result2 = false
- Result의 ‘hi’의 타입을 검사, ‘hi’는 string이기 때문에 조건문이 참이다. 따라 Result는 true가 된다.
- Result2의 [1]의 타입을 검사, [ 1 ]는 [number]이기때문에 조건문이 거짓이다. 따라 Result2는 false가 된다.
타입이 맞으면 배열로 만들고, 아닐 경우에는 nerver로 만들 때 사용 (예외처리)
제네릭과 함께 사용
1
2
3
type ChooseArray<A> = A extends string ? string[] : never;
type StringArr2 = ChooseArray<string>; // type StringArr2 = string
type NumberArr2 = ChooseArray<number>; // type NumberArr2 = never
- 타입 ChooseArray는
<A>
가 string이면 string[]로 만들고 아닐 경우 never가 된다.
중첩해서 사용 가능
1
2
3
4
5
6
7
8
9
10
11
12
type ChooseArray2<A> = A extends string
? string[]
: A extends boolean
? boolean[]
: never;
type StringArr3 = ChooseArray2<string>;
// type StringArr3 = string[]
type BooleanArr3 = ChooseArray2<boolean>;
// type BooleanArr3 = boolean[]
type NumberArr3 = ChooseArray2<number>;
// type NumberArr3 = never
1
2
3
type Start = string | number;
type Result = Start extends string ? Start[] : never;
// type Result = never
type Result = string | number extends string
string number이 string을 extends할 수 없기때문에 never가 됨
컨디셔널 타입을 제네릭과 함께 사용하면 Start[]타입으로 지정할 수 있음
1
2
3
4
5
type Start = string | number;
type Result<Key> = Key extends string ? Key[] : never;
// Key in type Result<Key>
// let n: string[]
let n: Result<Start> = ["hi"];
1
2
3
Result<Start>
=> type Result<string | number> = Result<string> | Result<number> extends string
=> string[]
boolean 분배법칙 막기
1
2
3
4
5
6
7
8
9
type Start = string | number | boolean;
type Result<Key> = Key extends string | boolean ? Key[] : never;
// Key in type Result<Key>
let n: Result<Start> = ["hi"];
// let n: string[]
n = [true];
// let n: string[] | false[] | true[]
string[] | boolean[]을 원했지만 [true]일 때는 string[] | false[] | true[] 로 boolean이 분배 법칙이 일어나 boolean을 false | true로 인식했기 때문 |
1
2
3
type IsString<T> = T extends string ? true : false;
type Result = IsString<"hi" | 3>;
// type Result = boolean
type Result = IsString<'hi'>
type Result = IsString<3>
;true
false
가 되기때문에- 최종적으로 boolean 타입이 됨
분배 법칙을 막으려면?
배열로 제네릭을 감싸면 분배법칙이 일어나지 않는다.
1
2
3
type IsString<T> = [T] extends [string] ? true : false;
type Result = IsString<"hi" | 3>;
// type Result = false
type Result = IsString<'hi' | 3> extends string
을 확인- 최종적으로 false 타입이 됨
This post is licensed under CC BY 4.0 by the author.