[타입스크립트] Promise, Awaited 타입?

ChuYong·2023년 10월 21일
0

Promise

Promise#catch

catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult> | undefined | null): Promise<T | TResult);

우선 일반적인 상황에서 (Promise T 제네릭 타입은 boolean이라고 가정) catch((e) ⇒ console.log(e)) 정도로 썼다고 가정하면

TResult는 void가 되어서 onrejected는 (reason: any) ⇒ void | PromiseLike<void> 가 된다.

모아서 써보면 결국 catch(onrejected: (reason: any) ⇒ void | PromiseLike<void>): Promise<boolean | void> 가 된다.

여기에 await 키워드를 붙이면 값은 boolean | void가 된다.

물론 onrejected의 리턴값이 string이었다면 boolean | string 이 됐을 것이다.

Promise.all

all<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T] : Awaited<T[P]> }>;

[P in keyof T] : Awaited<T[P]> 를 단순히 생각해보면

T를 쪼개서 key는 인덱스 value는 Awaited로 돌려주는 친구다.

결국 배열의 인수들이 Awaited를 타고 나오는걸 알 수 있다. Awaited는 뭘까?

Awaited

type Awaited<T> =
	T extends null | undefined ? T :
		T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ?
			(F extends ((value: infer V, ...args: infer _) => any) ?
				Awaited<V>: never): T;

Step 1. T extends null | undefined ? T : [다음]

T객체가 null이나 undefined면 그냥 null | undefined

Step 2. T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ? [다음] : T

T 객체가 object ( {} ) 형태가 아니면 (i.e. string, number, boolean 등) or then~~ 함수가 없으면 그대로 T,

즉 Awaited === NotObject

T 가 객체(object) 형태이면서 then(onfulfilled: infer F, ...args: infer _): any 를 가지고 있다면.. 다음식

참고로 Promise 는 then(onfulfilled: infer F, ...args: infer _): any 를 만족함

역으로 객체에 then(onfulfilled: infer F, ...args: infer _): any 가 있으면, await 키워드를 사용할 수 있다는 말도 됨 (구조적 타이핑).

Step3. F extends ((value: infer V, ...args: infer _) => any) ? Awaited: never

Promise.resolve('hello')
	.then((e) => e);

위 예시에서 then 함수 부분이 (value: infer V, ...args: infer _) => any 이 친구가 됨

Step 2단계에서의 F는 일반적인 then 사용법을 생각해보면 그냥 단순히 함수에 불과함 (실제 Promise의 제네릭 타입이 아님)

이때, V의 값이 실제 Promise의 원본 타입이 됨.

즉, Awaited<Promise<T>> === Awaited<T> 가 됨

Awaited 는 다시 Step1을 거쳐 결국 T가 된다.

profile
백엔드 & 인프라 를 좋아하는 개발자에요

0개의 댓글

관련 채용 정보