Hone logo
Hone
Problems

Implement Awaited Type Helper in TypeScript

Many asynchronous operations in JavaScript return Promises. When working with these Promises, you often need to extract the resolved value type of a Promise. This is crucial for type safety, especially when dealing with nested Promises or functions that return Promises. Your task is to implement a TypeScript utility type, similar to the built-in Awaited, that can recursively unwrap the type of a Promise.

Problem Description

You need to create a generic TypeScript type called MyAwaited<T>. This type should take a type T and return the type that T would resolve to if it were awaited.

Key Requirements:

  • If T is a Promise, MyAwaited<T> should be the type of the value the Promise resolves to.
  • If T is not a Promise, MyAwaited<T> should simply be T.
  • The type should handle nested Promises (e.g., Promise<Promise<number>>).
  • The type should also handle "thenable" objects, which are objects that have a then method, as these can also be awaited in JavaScript.

Expected Behavior:

  • MyAwaited<Promise<number>> should be number.
  • MyAwaited<Promise<Promise<string>>> should be string.
  • MyAwaited<number> should be number.
  • MyAwaited<{ then: (onfulfilled: (value: string) => void) => void }> should be string.

Examples

Example 1:

type Example1 = MyAwaited<Promise<number>>;
// Expected type: number

Explanation: Promise<number> is a Promise. Awaiting it resolves to number.

Example 2:

type Example2 = MyAwaited<Promise<Promise<string>>>;
// Expected type: string

Explanation: Promise<Promise<string>> is a Promise. Awaiting it resolves to Promise<string>. Awaiting that resolves to string.

Example 3:

type Example3 = MyAwaited<boolean>;
// Expected type: boolean

Explanation: boolean is not a Promise and does not have a then method. It is returned as is.

Example 4:

type Thenable = {
  then: (onfulfilled: (value: { data: number }) => void) => void;
};
type Example4 = MyAwaited<Thenable>;
// Expected type: { data: number }

Explanation: Thenable is an object with a then method, making it "thenable". MyAwaited should unwrap the type resolved by its then method.

Constraints

  • The solution must be a single generic type definition in TypeScript.
  • No runtime JavaScript code is required; this is a purely static type-level problem.
  • You cannot use the built-in Awaited utility type.

Notes

Consider how you can use conditional types (T extends U ? X : Y) and recursive type definitions to achieve this. Remember that Promise<T> and "thenable" objects are the primary targets for unwrapping. Think about the structure of a Promise and a thenable object.

Loading editor...
typescript