Typescript Challenges에 있는 타입스크립트 문제를 easy 단계부터 풀어 보고 있습니다. 3문제씩 풀이와 함께 업로드합니다.
Awaited
- https://github.com/type-challenges/type-challenges/blob/master/questions/189-easy-awaited/README.md
- 문제: Promise로 들어온 타입을 Promise 해제된 타입으로 변환하는 문제.
1) 우선 Promise 타입이 아닐 경우에는 에러가 발생해야 하기 때문에 generic 타입에 extends로 타입 제한을 부여합니다. T extends Promise<any>
2) 이제 Promise 안에 담긴 타입을 무엇인지 알아야 합니다. 이 때 필요한 키워드가 infer
라는 "타입 추론" 키워드입니다. infer K
라고 하게 되면 K의 타입을 추론하라는 뜻이 됩니다.
삼항연산자에서 사용하게 되면 해당 타입을 추론할 수 있으면 true 조건으로, 아니면 false 조건으로 실행됩니다.
이 문제에서는 Promise 안에 generic으로 감싸진 타입을 추론하고 싶은 것이므로 T extends Promise<infer U>
로 작성할 수 있습니다.
타입이 추론되면 U, 아니면 never로 지정해 봅니다. T extends Promise<infer U> ? U : never
3) 2번과 같이 하면 대부분의 문제에서는 해결이 되지만, Promise 이중 래핑된 구조에서는 아직 원하는 답을 얻기가 힘듭니다. 이중 Promise를 풀어낸 타입이어야 하기 때문입니다.Promise<Promise<string | number>> -> string | number
따라서 infer를 한 번 더 사용해 Promise안에 타입이 또 있는지에 대한 검사를 진행합니다.
type MyAwaited<T extends Promise<any>> = T extends Promise<infer U> ? U extends Promise<infer K> ? K : U : never;
// Promise 타입이 아닐 때 에러 발생하지 않아도 된다면, 재귀적으로 사용 가능합니다.
type MyAwaited<T> = T extends Promise<infer U> ? MyAwaited<U> : T;
If
- https://github.com/type-challenges/type-challenges/blob/master/questions/268-easy-if/README.md
- 문제: generic으로 삽입된 3개의 타입을 순서대로 condition, true type, false type으로 사용하여 condition에 따라 알맞은 타입을 반환하는 문제.
1) C
타입을 boolean 타입만 올 수 있도록 타입에 제한을 둡니다. C extends boolean
2) C
가 boolean 타입이므로 true, false만 올 수 있기 때문에 true인 경우에는 T, false는 F가 되도록 합니다. C extends true ? T : F
type If<C extends boolean, T, F> = C extends true ? T : F;
Concat
- https://github.com/type-challenges/type-challenges/blob/master/questions/533-easy-concat/README.md
- 문제: Javascript에서의 Array.concat 함수를 타입으로 구현하는 문제.
1) generic 타입을 배열로 제한해 두면 javascript와 같이 spread operator를 사용할 수 있습니다.
type Concat<T extends any[], U extends any[]> = [...T, ...U];