← Alle AufgabenTypeScript · Senior

Ein typisiertes Promise.all für Tupel

Schreib all(values), ein Gegenstück zu Promise.all, ohne Promise.all selbst zu nutzen. Es wartet auf alle Werte (Promises oder einfache), liefert die Ergebnisse in derselben Reihenfolge und lehnt mit dem ersten Fehler ab.

Die Hauptsache ist hier der Typ: für all([1, Promise.resolve("a")]) muss das Ergebnis Promise<[number, string]> sein, ein Tupel, nicht (string | number)[]. Verschachtelte Promises werden bis zum Wert ausgepackt.

Tests (7)

Typtests prüft der TypeScript-Compiler im strict-Modus. Expect<Equal<A, B>> besteht, wenn die Typen exakt gleich sind, und // @ts-expect-error, wenn die nächste Zeile nicht kompiliert. Der erste Start lädt den Compiler und dauert daher ein paar Sekunden.

  1. Typen
    const p = all([1, Promise.resolve('a'), Promise.resolve(true)]);
    type _ = Expect<Equal<typeof p, Promise<[number, string, boolean]>>>;
  2. Typen
    const p = all([1, 'x'] as const);
    type _ = Expect<Equal<typeof p, Promise<[1, 'x']>>>;
  3. Typen
    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([]);