Po_tta_tt0
콩심콩 팥심팥 🌱
Po_tta_tt0
전체 방문자
오늘
어제
  • 분류 전체보기 (266)
    • 🐛 회고 (14)
    • 💭 생각 (2)
    • 🤸‍♀️ 내 프로젝트 (16)
      • FISH-NEWS (8)
      • MBTI 과몰입 테스트 (2)
      • twitter clonecoding with TS (4)
      • pilzagenda (2)
    • 👨‍👩‍👧‍👦 팀 프로젝트 (2)
      • 피우다 프로젝트 (0)
      • SEMO(세상의 모든 모임) (1)
      • 마음을 전하는 텃밭 (1)
      • Stackticon (0)
    • 👨‍💻 CS지식 (11)
    • ✍ 공부 (94)
      • JavaScript (21)
      • TypeScript (39)
      • Html (0)
      • CSS (2)
      • React (18)
      • NextJS (7)
      • Vue (1)
      • Python (1)
      • Django (0)
      • 개발환경 & 그 외 (2)
    • 🏄‍♀️ 코딩테스트 (99)
      • 🐍 Python (99)
    • 🐙 Git & GitHub (3)
    • 📑 오류기록 (8)
    • 📚 우리를 위한 기록 (9)
    • 수업 (3)
    • 강의 등 (2)
    • 👩‍🎓 SSAFY (0)
    • 👋 우테코 (0)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • dfs
  • 구현
  • 파이썬 다익스트라
  • Next.js
  • React
  • 파이썬 감시 피하기
  • 백준
  • 시뮬레이션
  • DP
  • js
  • 백준 파이썬
  • bfs
  • 플로이드 워셜
  • 파이썬
  • 백준 숨바꼭질
  • 문자열
  • 자바스크립트
  • react-router-dom
  • BFS + DP
  • 이분탐색

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Po_tta_tt0

콩심콩 팥심팥 🌱

✍ 공부/TypeScript

[type-challenges] Awaited

2023. 5. 23. 19:22
반응형

 

 

 

0. 문제

Promise와 같은 타입에 감싸진 타입이 있을 때, 안에 감싸진 타입이 무엇인지 찾아보자

 

 

 

 

 

1. 설명

/* _____________ Your Code Here _____________ */

type MyAwaited<T> = T extends Promise<infer P> ? P extends Promise<any> ? MyAwaited<P> : P :
T extends { then: (onfulfilled: (arg: infer K) => any) => any } ? K : error

type MyAwaited2<T extends {then:unknown}> = Awaited<Promise<T>> 


/* _____________ 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>

 

 

추가설명

첫번째 방법

type MyAwaited<T> = T extends Promise<infer P> ? P extends Promise<any> ? MyAwaited<P> : P :
T extends { then: (onfulfilled: (arg: infer K) => any) => any } ? K : error

이런 방식으로 해결할 수 있다.
다중 if문을 쪼개서 생각해보자

  1. T extends Promise<infer P> ? T가 Promise를 extends할 때 작동시킬 부분 : T가 Promise를 extends하지 않을 때 작동시킬 부분
    • T가 Promise를 extends할 때 작동시킬 부분
    • P extends Promise<any> ? MyAwaited<P> : P
    • P가 Promise를 extends한다면 MyAwaited<P>로 재귀를 돌아주고, 그게 아니라면 그냥 P를 출력해준다
      • T가 Promise를 extends하지 않을 때 작동시킬 부분
    • T extends { then: (onfulfilled: (arg: infer K) => any) => any } ? K : error
    • T는 typeT에 적합한 타입인지 확인하고 맞다면 K를 출력, 아니라면 error을 표출한다

 

 

쪼개서 생각하니까 간단하다.
type T를 아예 가져다 박아서 해결한 방법이다.

 

 

 

 

두번째 방법

type MyAwaited2<T extends {then:unknown}> = Awaited<Promise<T>> 

이 방법을 통해 Awaited에 대해서 알게 되었다.
T는 항상 {then:unknown}을 extends하고,

Awaited<T> 타입이란?

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<...> : never : T

음..?
공식문서를 보자

 

 

공식문서

The Awaited Type and Promise Improvements
TypeScript 4.5 introduces a new utility type called the Awaited type. This type is meant to model operations like await in async functions, or the .then() method on Promises - specifically, the way that they recursively unwrap Promises.

// A = string
type A = Awaited<Promise<string>>;
// B = number
type B = Awaited<Promise<Promise<number>>>;
// C = boolean | number
type C = Awaited<boolean | Promise<number>>;

The Awaited type can be helpful for modeling existing APIs, including JavaScript built-ins like Promise.all, Promise.race, etc. In fact, some of the problems around inference with Promise.all served as motivations for Awaited. Here’s an example that fails in TypeScript 4.4 and earlier.

declare function MaybePromise<T>(value: T): T | Promise<T> | PromiseLike<T>;
async function doSomething(): Promise<[number, number]> {
  const result = await Promise.all([MaybePromise(100), MaybePromise(200)]);
  // Error!
  //
  //    [number | Promise<100>, number | Promise<200>]
  //
  // is not assignable to type
  //
  //    [number, number]
  return result;
}

Now Promise.all leverages the combination of certain features with Awaited to give much better inference results, and the above example works.

For more information, you can read about this change on GitHub.

 

 

비동기 함수의 await 또는 Promise의 .then() 메서드, 특히 재귀적으로 Promise를 언래핑하는 방식과 같은 작업을 수행하는 유틸리티 타입이다.

 

두번째 방법 type MyAwaited2<T extends {then:unknown}> = Awaited<Promise<T>>
이 이렇게 짧은 이유가 여기 있다


+T가 {then:unknown}을 해야 하는 이유는 이를 수행하지 않으면 type T 또한 error가 찍히기 떄문이다

 

 

반응형
저작자표시 (새창열림)

'✍ 공부 > TypeScript' 카테고리의 다른 글

[type-challenges] Concat  (0) 2023.05.23
[type-challenges] If  (0) 2023.05.23
[type-challenges] Exclude  (0) 2023.05.23
[type-challenges] Length of Tuple  (0) 2023.05.23
[type-challenges] First of Array  (0) 2023.05.23
    '✍ 공부/TypeScript' 카테고리의 다른 글
    • [type-challenges] Concat
    • [type-challenges] If
    • [type-challenges] Exclude
    • [type-challenges] Length of Tuple
    Po_tta_tt0
    Po_tta_tt0
    감자의 코딩하는 블로그 콩심은데 콩나고 팥심은데 팥난다

    티스토리툴바