← Усі задачіTypeScript · Senior

Типізований Promise.all для кортежів

Напишіть all(values) - аналог Promise.all без самого Promise.all. Він чекає на всі значення (проміси чи звичайні), повертає результати в тому самому порядку й відхиляється з першою помилкою.

Головне тут - тип: для all([1, Promise.resolve("a")]) результат має бути Promise<[number, string]>, кортеж, а не (string | number)[]. Вкладені проміси розгортаються до значення.

Тести (7)

Тести типів перевіряє компілятор TypeScript у режимі strict. Expect<Equal<A, B>> проходить, коли типи збігаються точно, а // @ts-expect-error - коли наступний рядок не компілюється. Перший запуск завантажує компілятор, тож триває кілька секунд.

  1. типи
    const p = all([1, Promise.resolve('a'), Promise.resolve(true)]);
    type _ = Expect<Equal<typeof p, Promise<[number, string, boolean]>>>;
  2. типи
    const p = all([1, 'x'] as const);
    type _ = Expect<Equal<typeof p, Promise<[1, 'x']>>>;
  3. типи
    const p = all([] as unknown as [Promise<Promise<number>>, string]);
    type _ = Expect<Equal<typeof p, Promise<[number, string]>>>;
  4. expect(await all([1, Promise.resolve(2), wait(20).then(() => 3)])).toEqual([1, 2, 3]);
  5. const slow = wait(30).then(() => 'slow');
    const fast = Promise.resolve('fast');
    expect(await all([slow, fast])).toEqual(['slow', 'fast']);
  6. await expect(all([Promise.resolve(1), Promise.reject(new Error('boom'))])).rejects.toThrow('boom');
  7. expect(await all([])).toEqual([]);