From cedfdc2d787d570580494a03218f9d8ffc6e48f5 Mon Sep 17 00:00:00 2001 From: Niles Salter Date: Mon, 8 Aug 2022 16:18:18 -0500 Subject: [PATCH 1/2] Fix Promise.all/allSettled/race/some/any - `all` no longer accepts non-promises in the input array - `allSettled` now preserves array/tuple length where possible - `some` can take in a positive, non-decimal numeric literal type and convert it to a tuple of the right length. - `all`/`allSettled`/`race`/`some`/`any` now all: - accept readonly arrays, since these methods don't mutate in-place - accept arrays with different Promise types in them, e.g. `[Promise, Promise]` now works - for `race`/`any`, we transform `[Promise, Promise]` into `Promise` rather than `Promise | Promise`. For `some` it is the same but an array: `Promise<(number | string)[]>` --- types/Promise.d.ts | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/types/Promise.d.ts b/types/Promise.d.ts index 7789335..21c96a9 100644 --- a/types/Promise.d.ts +++ b/types/Promise.d.ts @@ -387,7 +387,7 @@ interface PromiseConstructor { * return Promise.all(promises) * ``` */ - all: >(values: readonly [...T]) => Promise<{ [P in keyof T]: Awaited }>; + all: >>(promises: T) => Promise<{ [P in keyof T]: Awaited }>; /** * Accepts an array of Promises and returns a new Promise that resolves with an array of in-place Statuses when all input Promises have settled. This is equivalent to mapping `promise:finally` over the array of Promises. @@ -402,7 +402,7 @@ interface PromiseConstructor { * return Promise.allSettled(promises) * ``` */ - allSettled: (promises: Array>) => Promise>; + allSettled: >>(promises: T) => Promise<{ [P in keyof T]: Promise.Status }>; /** * Accepts an array of Promises and returns a new promise that is resolved or rejected as soon as any Promise in the array resolves or rejects. @@ -422,7 +422,7 @@ interface PromiseConstructor { * return Promise.race(promises) * ``` */ - race: (promises: Array>) => Promise; + race: >(promises: ReadonlyArray) => Promise>; /** * Accepts an array of Promises and returns a Promise that is resolved as soon as `count` Promises are resolved from the input array. The resolved array values are in the order that the Promises resolved in. When this Promise resolves, all other pending Promises are cancelled if they have no other consumers. @@ -439,7 +439,7 @@ interface PromiseConstructor { * return Promise.some(promises, 2) -- Only resolves with first 2 promises to resolve * ``` */ - some: (promises: Array>, count: number) => Promise>; + some: , N extends number>(promises: ReadonlyArray, count: N) => Promise, N>>; /** * Accepts an array of Promises and returns a Promise that is resolved as soon as _any_ of the input Promises resolves. It will reject only if _all_ input Promises reject. As soon as one Promises resolves, all other pending Promises are cancelled if they have no other consumers. @@ -455,7 +455,7 @@ interface PromiseConstructor { * return Promise.any(promises) -- Resolves with first value to resolve (only rejects if all 3 rejected) * ``` */ - any: (promises: Array>) => Promise; + any: >(promises: ReadonlyArray) => Promise>; /** * Returns a Promise that resolves after `seconds` seconds have passed. The Promise resolves with the actual amount of time that was waited. @@ -621,3 +621,24 @@ declare namespace Promise { } declare const Promise: PromiseConstructor; + +/** internal */ +declare namespace TS { + /** Returns a Tuple of size N filled with T */ + type BuildTupleUnchecked = []> = A extends { length: infer L } + ? L extends N + ? A + : BuildTupleUnchecked + : never; + + /** Returns a Tuple of size N filled with T, but defaults to Array if N is `number`, or negative, or a decimal. */ + type BuildTuple = N extends number + ? number extends N + ? Array + : `${N}` extends `-${string}` + ? Array + : `${N}` extends `${string}.${string}` + ? Array + : BuildTupleUnchecked + : never; +} From fd6902c3ffa255fcc4846654c108b920ca227b0b Mon Sep 17 00:00:00 2001 From: Niles Salter Date: Mon, 8 Aug 2022 16:23:05 -0500 Subject: [PATCH 2/2] Prettier fix --- types/Promise.d.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types/Promise.d.ts b/types/Promise.d.ts index 21c96a9..372a085 100644 --- a/types/Promise.d.ts +++ b/types/Promise.d.ts @@ -439,7 +439,10 @@ interface PromiseConstructor { * return Promise.some(promises, 2) -- Only resolves with first 2 promises to resolve * ``` */ - some: , N extends number>(promises: ReadonlyArray, count: N) => Promise, N>>; + some: , N extends number>( + promises: ReadonlyArray, + count: N, + ) => Promise, N>>; /** * Accepts an array of Promises and returns a Promise that is resolved as soon as _any_ of the input Promises resolves. It will reject only if _all_ input Promises reject. As soon as one Promises resolves, all other pending Promises are cancelled if they have no other consumers.