일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- hook
- javascript
- frontend
- satisfiles
- Redux
- Chakra
- Spring
- Gin
- 티스토리챌린지
- java
- component
- backend
- 오블완
- go
- JavaSpring
- test
- designpatterns
- ReactHooks
- storybook
- React
- css
- springboot
- react-hook-form
- JPA
- typescript
- tanstackquery
- golang
- RTK
- 웹애플리케이션서버
- Today
- Total
bkdragon's log
Conditional types 본문
타입을 정의할 때 입력에 따라서 다르게 정의할 수 있을까? 당연히 가능하다. 대부분의 프로그래밍 언어처럼 타입스크립트에서도 if문의 역할을 하는 기능이 있다. 바로 Conditional types이다.
T extends U ? X : Y
T타입이 적어도 U타입이라면 X타입 아니라면 Y타입이 된다.
이 개념을 사용한 타입챌린지 문제를 보자.
https://github.com/type-challenges/type-challenges/blob/main/questions/00268-easy-if/README.ko.md
if 타입을 구현하는 문제인데, C타입 참일 때 T, 거짓을 때 F를 반환해야한다. Conditional types을 이용하면 다음과 같이 작성할 수 있다.
type If<C, T, F> = C extends true ? T : F;
그런데 여기까지만 하면 예외처리가 안된다. C로 어떠한 타입도 대입이 될 수 있다.
constraint(제약조건)을 줄 수 있다.
type If<C extends boolean, T, F> = C extends true ? T : F;
이렇게 되면 C 타입에는 적어도 boolean 타입만 대입될 수 있다.
Conditional types를 이용하여 타입 추론도 가능하다. infer 키워드를 이용한다. 타입을 정의하는 시점에서 알 수 없는 타입을 가상의 타입으로 정하고 사용한다.
리턴 타입을 반환해야하는 문제이다. 타입을 정의하는 시점에서는 무슨 타입이 반환될지 모르니 infer를 사용할 수 있다.
type MyReturnType<T extends (...arg : any[]) => any > = T extends (...arg : any[]) => infer R ? R : never;
추가적으로 알아둬야할 유용한 개념이 있다. Distributive Conditinal types, Conditinal types이 유니온 타입을 만나면 분산적으로 동작한다는 개념이다.
Exclude 타입을 구현하는 문제이다.
type MyExclude<T, U> = T extends U ? never : T;
정답은 다음과 같다. T가 유니온 타입이라면 하나씩 U와 비교하고 결과 역시 유니온 타입으로 나올 것이다.
그런데 T가 유니온 타입이라고 제약조건을 걸 필요가 있을까? 전혀 없다. 아니면 아닌거니까!
마지막으로 문제를 하나만 더 살펴보려고 한다.
Lookup 타입을 구현하는 문제이다. 유니온 타입의 특정 속성을 기준으로 조회한다. U가 유니온 타입인걸 알았으니 약간 꼼수로 extends에 왼쪽에 오겠구나 하고 생각할 수도 있다.
type LookUp<U, T> = U extends {type : T} ? U : never;
여러가지 문제를 통해 Conditinal types를 알아보았다.
'Typescript' 카테고리의 다른 글
satisfies 키워드란? (0) | 2023.07.02 |
---|---|
Template Literal Types (0) | 2023.04.04 |
Chainable Options (0) | 2023.03.14 |
Deep Readonly (0) | 2023.03.10 |
key in keyof T as key extends K ? never : key ??? (0) | 2023.03.03 |