# 00. Awaited

> 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?
>
> [문제링크](https://github.com/type-challenges/type-challenges/blob/master/questions/189-easy-awaited/README.md), [해설](https://ghaiklor.github.io/type-challenges-solutions/en/easy-awaited.html)

문제는 타입의 `unwrap` 을 할수있는지 물어본다. `unwrap` 이란 무엇인가? `Promise<string>` 이 있을 때 `Promise` 를 언랩핑하면 `string` 이라는 `inner type` 을 얻을 수 있다.

```typescript
// 0. 시작
type Awaited = any

// 1. Awaited 의 제네릭으로 들어는 T는 Promise<> 의 형태여야한다.
type Awaited<T extends Promise<any>> = any

// 2. T 가 Promise<> 을 extends 하는지 알아본다. 만약 알맞은 형태라면 aa 가 inner type 이 된다.
type Awaited<T extends Promise<unknown>> = T extends Promise<> ? aa : bb

// 3. Promise 의 <> 에는 어떠한 타입이든지 다 들어올 수 있다. 따라서 '추론' 하자
// 추론된 타입은 R 이다.
type Awaited<T extends Promise<unknown>> = T extends Promise<infer R> ? aa : bb

// 4. Awaited의 제네릭 인자로 들어온 형태가 알맞은 Promise 형태라면, 추론한 R 을 리턴하면 된다.
type Awaited<T extends Promise<unknown>> = T extends Promise<infer R> ? R : T
```

1번부터 너무 어려운 문제였다. 해설을 보면서 학습했다. 문제의 핵심은 두가지다.

1. `Conditional Types` 를 할 수 있는가?
2. `Conditional Types` 에서의 추론

만약 1, 2번이 이해가 되지 않는다면 [타입스크립트 핸드북](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html), 또는 [내가 정리한 조건부타입](https://simian114.gitbook.io/blog/undefined/undefined-3/conditional-types)을 보고오자. 1, 2를 이해했다면 이제 문제를 풀어보자.

```typescript
// 1. 제레릭 인자로 들어오는 T 의 타입은 Promise<any> 다.
// 그리고 우리는 any 의 타입을 추론해서 결정하고싶음
type Awaited = any

type Awaited<T> = ....

type Awaited<T extends Promise<any>> = ...;

type Awaited<T extends Promise<any>> = T extends Promise<> ? xx : yy;

type Awaited<T extends Promise<any>> = T extends Promise<infer R> ? R : T;
```
