00189-easy-awaited

Back

// 你的答案
type MyAwaited<T> = T extends Promise<infer R> ? R extends Promise<infer M> ? MyAwaited<R> : R : T extends {
  then:(arg1:(arg2:infer Q)=>any,...args:any)=>any} ? Q :never

Solution by front-end-Dean #35268

type MyAwaited<T> = T extends PromiseLike<infer U> ? MyAwaited<U> : T

I’m not sure if this is correct, but the test cases didn’t report any errors.

Solution by kid1110 #35178

// 你的答案
type Thenable<T> = {
  then: (onfulfilled: (arg: T) => unknown) => unknown;
}

type MyAwaited<T> = T extends Promise<infer Inner> | Thenable<infer Inner> ? MyAwaited<Inner> : T

Solution by HoseaGuo #35127

type MyAwaited<T> = T extends Promise<infer P> ? P : never

Solution by ClarityOfMind #34988

type MyAwaited<T> = T extends Promise<infer U> ? U : T;

Solution by raeyoung-kim #34939

type MyAwaited = T extends PromiseLike ? MyAwaited

: T;

no so complex,just this!

Solution by shx123qwe #34928

Answers: type MyAwaited<T> = T extends Promise<infer R> ? MyAwaited<R> : T extends { then: (onfulfilled: (arg: infer U) => any) => any } ? U : T; 

Understanding the MyAwaited Type Utility in TypeScript
Introduction
In TypeScript, working with asynchronous code often involves using promises. When dealing with promises, it can be helpful to extract the type that a promise resolves to. This is where a utility type like MyAwaited comes into play. MyAwaited allows developers to retrieve the resolved type of a promise, even when dealing with nested promises. This article will explore the implementation and functionality of MyAwaited.

Purpose of MyAwaited
The primary goal of the MyAwaited type utility is to take a promise type and return the type that it resolves to. Additionally, MyAwaited can handle promises that are nested within other promises and can also work with objects that resemble promises, such as those with a then method.

Implementation of MyAwaited
Here’s the implementation of the MyAwaited type utility:

type MyAwaited<T> = 
  T extends Promise<infer R>
    ? MyAwaited<R> // Recursive check for nested promises
    : T extends { then: (onfulfilled: (arg: infer U) => any) => any }
      ? U  // Handling objects with a `then` method
      : T; // Return T if not a promise or similar object

How It Works
Recursive Handling of Nested Promises:

The type utility begins by checking if T is a promise using the conditional type T extends Promise<infer R>.
If T is indeed a promise, it uses infer R to extract the resolved type R of that promise.
Then, MyAwaited<R> is invoked recursively to check if R itself is a promise, allowing the utility to navigate through any nested promises until it finds the ultimate resolved type.
Handling Promise-like Objects:

The second conditional check, T extends { then: (onfulfilled: (arg: infer U) => any) => any }, allows MyAwaited to work with objects that implement a then method, resembling a promise.
If T meets this condition, it infers the type U from the argument of the then method and returns it.
Default Case:

If T is neither a promise nor an object with a then method, it simply returns T

Solution by ESGAntall #34910

type MyAwaited<T extends PromiseLike<any>> = 
  T extends PromiseLike<infer U> 
    ? U extends PromiseLike<any>
      ? MyAwaited<U>
      : U
    : never; // Since there is a constraint with using PromiseLike interface, no need to return T type here. 

Solution by highspirit7 #34901

type MyAwaited<T> = T extends PromiseLike<infer P> ? (P extends PromiseLike<any> ? MyAwaited<P> : P): never

Solution by nguyste #34855

type MyAwaited<T> = T extends Promise<infer R> 
  ? MyAwaited<R> 
  : T extends { then: ( onfulfilled: (arg: infer D) => any) => any } 
    ? D 
    : T

Solution by eunsukimme #34812

type MyAwaited<T> = 
  T extends PromiseLike<infer R> 
    ? R extends PromiseLike<any> 
      ? MyAwaited<R> 
      : R 
    : never
image

Solution by Git-I985 #34702

// your answers
T 需要符合 PromiseLike 接口的类型约束
type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer R>
  ? R extends PromiseLike<any>
    ? MyAwaited<R>
    : R
  : never;

Solution by zeyuanHong0 #34691

type MyAwaited<T> = T extends PromiseLike<infer S> ? S extends PromiseLike<any> ? MyAwaited<S> : S : never;

Solution by nathan2slime #34659

type MyAwaited<T> = Awaited<T>

Solution by Hailey0930 #34636

// your answers
type MyAwaited<T> = T extends PromiseLike<infer U> ? MyAwaited<U> : T;

Solution by pwn0x80 #34585

type MyAwaited<T> = T extends PromiseLike<infer U>
  ? U extends PromiseLike<any>
    ? MyAwaited<U>
    : U
  : never

Solution by devshinthant #34544

// 여기 풀이를 입력하세요
type MyAwaited<T> = T extends Promise<infer P>
  ? MyAwaited<P>
  : T extends { then: (onfulfilled: (arg: infer U) => any) => any }
    ? MyAwaited<U>
    : T;

Solution by LeeKangHyun #34457

type MyTypeAwaited<T> = T extends Promise<infer R> ? MyTypeAwaited<R> :
    T extends { then: (onfulfilled: (arg: number) => any) => any } ? number : T;

Solution by ssriyathuae #34452

type MyAwaited<T> = T extends Promise<infer P> | { then: (...args: any) => any } ? MyAwaited<P> : T;

Solution by ktim816 #34423

// 你的答案
type MyAwaited<T> = T extends PromiseLike<infer R> ? MyAwaited<R> : T

使用 PromiseLike来过最后一个用例

Solution by Onweekendd #34409

type MyAwaited<T extends Promise<unknown>> = T extends Promise<infer P> ? (P extends Promise<unknown> ? MyAwaited<P> : P) : never;

//测试案例
type T = { then: (onfulfilled: (arg: number) => any) => any }

写成上面这种形式,最后一个测试案例无法通过。这是因为在TS中,通过Promise表示一个泛型类型,它提供了完整的异步操作处理机制,包括错误处理、链式调用和async/await支持。而PromiseLike仅要求对象具有then方法,功能可能不完整。因此PromiseLike主要用于类型兼容性和泛型编程中。在最后一个测试案例中,由于最后一个对象T是一个固定的函数类型,不带有Promise类型,因此应该采用PromiseLike。在后面的泛型中,由于unknown类型会进行Promise的断言检查,而最后一个测试案例不满足该要求,故泛型应该为any而不是unknown。

type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer P> ? (P extends PromiseLike<any> ? MyAwaited<P> : P) : never;

Solution by wxh-cyber #34403

type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U> 
  ? U extends PromiseLike<any> ? MyAwaited<U> : U 
  : never

Solution by rookie-luochao #34361

type MyAwaited<T> = T extends Promise<infer P> ? P extends Promise<unknown> ? MyAwaited<P> : P : never;

这里需要考虑到Promise内部还可以嵌套Promise的情况。

Solution by wxh-cyber #34336

type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer R> 
  ? R extends PromiseLike<any> 
    ? MyAwaited<R>
    : R
  : never

Solution by souzaramon #34316

type MyAwaited<T> = T extends Promise<infer U>
  ? MyAwaited<U>
  : T extends { then: (onfulfilled: (args: infer U) => any) => any }
  ? MyAwaited<U>
  : T;

Solution by 1Chen1y1111 #34311

// 你的答案

type MyAwaited = T extends PromiseLike ? A extends PromiseLike?MyAwaited:A : never

Solution by W-fitTiger #34246

We should know ts support recursive(?) type definition. And then, use PromiseLike or Partial type for passing test type T = { then: (onfulfilled: (arg: number) => any) => any }.

type MyAwaited<T> = T extends PromiseLike<infer K>? MyAwaited<K> : T

Solution by dev-jaemin #34160

문제설명

Promise와 같은 타입에 감싸인 타입이 있을 때, 안에 감싸인 타입이 무엇인지 어떻게 알 수 있을까요?

예시: 들어 Promise<ExampleType>이 있을 때, ExampleType을 어떻게 얻을 수 있을까요?

type ExampleType = Promise<string>;

type Result = MyAwaited<ExampleType>; // string

풀이

type MyAwaited<T> = T extends Promise<infer U> ? U : never;

처음에는 다음과 같이 작성하여 문제를 풀었습니다. infer를 사용하여 조건절에서의 타입을 예측해 추출합니다. 하지만 제귀적으로 Promise내부에 Promise가 선언되어 있는 test가 있어 수정했습니다.

type MyAwaited<T> = T extends Promise<infer U>
	? U extends Promise<any>
		? MyAwaited<U>
		: U
	: T;

하지만 마지막 test에서 문제가 발생했습니다.

type T = { then: (onfulfilled: (arg: number) => any) => any }; // 문제 발생

다음과 같은 예시에서는 Promise로는 해결되지 않습니다. 따라서 then을 포함하는 메서드인 PromiseLike를 사용합니다

Solution

/* _____________ 여기에 코드 입력 _____________ */

type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U>
	? U extends PromiseLike<any>
		? MyAwaited<U>
		: U
	: never;
/* _____________ 테스트 케이스 _____________ */
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>>
];

Solution by adultlee #34125

type loop<M> =  M extends (PromiseLike<infer A>) ? loop<A> : M;

type MyAwaited<T> =  loop<T>;

Solution by lidom1 #34098

type MyAwaited<T> = T extends PromiseLike<infer U>
    ? MyAwaited<U>
    : T

Solution by IllegalCreed #33999