
/*
189 - Awaited
-------
by Maciej Sikora (@maciejsikora) #easy #promise #built-in
### Question
If we have a type which is wrapped type like Promise. How we can get a type which is inside the wrapped type?
For example: if we have `Promise<ExampleType>` how to get ExampleType?
type ExampleType = Promise<string>
type Result = MyAwaited<ExampleType> // string
> This question is ported from the [original article](https://dev.to/macsikora/advanced-typescript-exercises-question-1-45k4) by [@maciejsikora](https://github.com/maciejsikora)
> View on GitHub: https://tsch.js.org/189
*/
/* _____________ Your Code Here _____________ */
// 예시코드
// type MyAwaited<T> = any
type MyAwaited<T extends Promise<any>> = T extends Promise<infer U> ? U extends Promise<infer K> ? K : U : never;
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type X = Promise<string>
type Y = Promise<{ field: number }>
type Z = Promise<Promise<string | number>>
type Z1 = Promise<Promise<Promise<string | boolean>>>
type T = { then: (onfulfilled: (arg: number) => any) => any }
type cases = [
Expect<Equal<MyAwaited<X>, string>>,
Expect<Equal<MyAwaited<Y>, { field: number }>>,
Expect<Equal<MyAwaited<Z>, string | number>>,
Expect<Equal<MyAwaited<Z1>, string | boolean>>,
Expect<Equal<MyAwaited<T>, number>>,
]
// @ts-expect-error
type error = MyAwaited<number>
/* _____________ Further Steps _____________ */
/*
> Share your solutions: https://tsch.js.org/189/answer
> View solutions: https://tsch.js.org/189/solutions
> More Challenges: https://tsch.js.org
*/
시작전에 생각했던 힌트
type MyAwaited<T extends PromiseLike<any>> = any
infer 라는 타입추론 키워드를 사용.infer K 라고 하게되면 K의 타입을 추론하라는 뜻.type MyAwaited<T extends PromiseLike<any>> = infer U
T extends Promise<infer U>type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U> ? ... : ...
type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U> ? U : never
Promise<Promise<string | number>> => string | numbertype MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U> ? U extends PromiseLike<infer K> ? MyAwaited<U> : U : never;
⭐️ 추가로 Promise 타입이 아닐 때 에러가 발생하지 않아도 된다면, 재귀적으로 사용 가능
type MyAwaited<T> = T extends PromiseLike<infer U> ? MyAwaited<U> : T;
의도를 생각하면서 한번 정리해보는 것이 좋을것같다.
더 좋은 답이라고 생각.
type RecursivePromise<T> = T extends PromiseLike<infer U>
? RecursivePromise<U>
: T
type MyAwaited<T extends PromiseLike<any>> = RecursivePromise<T>
⭐️ 생각보다 많이 어려웠다. 아직은 익숙하지 않은 Promise관련해서의 공부가 조금 더 필요하다.
출처