Promise.all under the hood

Example of Promise.all use

Today we discuss Promise.all

This is helpful in case we need to wait for all the values (e.g. we pass [Promise<number>, 42, Promise<string>] and expect to have Promise<[number, 42, string]> at the end).

Letโ€™s solve it ๐Ÿš€

Iteration over tuple elements

Previously, one of the challenges in easy category was Unwrapping the Promises where we imitated await in types:

Awaited solution

This will help to iterate over tuple elements and replace Promise with the resolved type.

We already know how to iterate over tuple elements with Making object out of tuple but here we have the difference:

  1. If we want to have elements of tuple inside the object type, we use Mapped Types:

Tuple in object type

  1. If we need to work with tuple elements and leave the structure as is, we use Type inference in conditional types with Rest elements in Tuples:

Tuple in tuple

As we need to transform the elements inside the tuple but still need to have the tuple at the end, we will use the second approach. Letโ€™s go over all elements and unwrap it with Awaited:

Promise reducer over arrays

The only thing we need to do is to apply it to PromiseAll:

Solution, version 1

Letโ€™s see what happened in Playground. We still have failed tests. But why?

Fixing the issues with values

If we hover over constants we will see that the result is Promise<[]>, but we expected it to have elementsโ€™ types inside a tuple.

This happens because as const converts an array to a tuple. For tuples T extends [infer H, ...infer Tail] ? true : false returns false because we forgot readonly keyword.

But instead of changing PromiseReducer letโ€™s have a look at promiseAllTest3:

Type inferred from promiseAllTest3

Type T is inferred as (number | Promise<number>)[] instead of [number, number, Promise<number>]. There is an approach to have values as tuple instead of array in types:

Make the values a tuple

  1. We added [...T] instead of T
  2. We say that [...T] is readonly to work with tuples only
  3. We added Generic Constrain to use spread in tuples

All together:

Solution

Thatโ€™s it ๐Ÿ”ฅ

Solution is available on Playground

Have a wonderful evening ๐ŸŒ‡

typescriptmedium

Let's chat and have fun ๐Ÿง‘โ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป

No more often than once a week I write ๐Ÿ“„ about TypeScript ๐Ÿ’ช, video playback ๐Ÿ“บ and frontend related topics. You can unsubscribe in any time โ†˜๏ธ

ยฉ 2021, Built with Gatsby