Implement a type-safe version of Promise.all that preserves tuple types and recursively unwraps nested promises. Master advanced TypeScript techniques including recursive types, mapped types, and conditional types in this medium-level challenge on TypeScriptPro.
In this medium-level challenge, you'll implement a type-safe version of Promise.all that preserves tuple types and recursively unwraps nested promises.
This challenge goes beyond basic promise handling by requiring you to preserve the exact tuple structure of the input array while recursively unwrapping all nested promises.
Type the function PromiseAll that accepts an array of PromiseLike objects, the returning value should be Promise<T> where T is the resolved result array.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise<string>((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
// expected to be `Promise<[number, 42, string]>`
const p = PromiseAll([promise1, promise2, promise3] as const)Change the following code to make the test cases pass (no type check errors).
The key insight is that we need to preserve the exact tuple type of the input array while recursively unwrapping all promises. Here's the solution:
type RecursivelyUnwrapPromise<T> =
T extends PromiseLike<infer Val> ? RecursivelyUnwrapPromise<Val> : T
declare function PromiseAll<T extends unknown[]>(
values: readonly [...T],
): Promise<{ [K in keyof T]: RecursivelyUnwrapPromise<T[K]> }>Let's break this down:
T extends unknown[] ensures the input is an array typereadonly [...T] preserves the exact tuple structure (e.g., [number, number, number] instead of number[])RecursivelyUnwrapPromise<T[K]> recursively unwraps each promise in the tuple, by calling itself with the value of the promise if that value is PromiseLike.{ [K in keyof T]: ... } maps over each element in the tuplePromise<...> to match the expected return typeThe recursive utility type RecursivelyUnwrapPromise<T> handles cases where promises might be nested within promises, ensuring all levels are properly unwrapped while maintaining type safety.
This challenge helps you understand advanced TypeScript concepts like recursive types, mapped types, and how to preserve precise type information through complex transformations.
This challenge is originally from here.
Be the first to access the course, unlock exclusive launch bonuses, and get special early-bird pricing before anyone else.
Only 27 Spots left
Get 1 month early access
Pre-Launch discount