Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Promise.all/allSettled/race/some/any #140

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions types/Promise.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ interface PromiseConstructor {
* return Promise.all(promises)
* ```
*/
all: <T extends Array<unknown>>(values: readonly [...T]) => Promise<{ [P in keyof T]: Awaited<T[P]> }>;
all: <T extends ReadonlyArray<Promise<unknown>>>(promises: T) => Promise<{ [P in keyof T]: Awaited<T[P]> }>;

/**
* 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.
Expand All @@ -402,7 +402,7 @@ interface PromiseConstructor {
* return Promise.allSettled(promises)
* ```
*/
allSettled: <T>(promises: Array<Promise<T>>) => Promise<Array<Promise.Status>>;
allSettled: <T extends ReadonlyArray<Promise<unknown>>>(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.
Expand All @@ -422,7 +422,7 @@ interface PromiseConstructor {
* return Promise.race(promises)
* ```
*/
race: <T>(promises: Array<Promise<T>>) => Promise<T>;
race: <T extends Promise<unknown>>(promises: ReadonlyArray<T>) => Promise<Awaited<T>>;

/**
* 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.
Expand All @@ -439,7 +439,10 @@ interface PromiseConstructor {
* return Promise.some(promises, 2) -- Only resolves with first 2 promises to resolve
* ```
*/
some: <T>(promises: Array<Promise<T>>, count: number) => Promise<Array<T>>;
some: <T extends Promise<unknown>, N extends number>(
promises: ReadonlyArray<T>,
count: N,
) => Promise<TS.BuildTuple<Awaited<T>, 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.
Expand All @@ -455,7 +458,7 @@ interface PromiseConstructor {
* return Promise.any(promises) -- Resolves with first value to resolve (only rejects if all 3 rejected)
* ```
*/
any: <T>(promises: Array<Promise<T>>) => Promise<T>;
any: <T extends Promise<unknown>>(promises: ReadonlyArray<T>) => Promise<Awaited<T>>;

/**
* Returns a Promise that resolves after `seconds` seconds have passed. The Promise resolves with the actual amount of time that was waited.
Expand Down Expand Up @@ -621,3 +624,24 @@ declare namespace Promise {
}

declare const Promise: PromiseConstructor;

/** internal */
declare namespace TS {
/** Returns a Tuple of size N filled with T */
type BuildTupleUnchecked<T, N extends number, A extends Array<any> = []> = A extends { length: infer L }
? L extends N
? A
: BuildTupleUnchecked<T, N, [...A, T]>
: never;

/** Returns a Tuple of size N filled with T, but defaults to Array<T> if N is `number`, or negative, or a decimal. */
type BuildTuple<T, N extends number> = N extends number
? number extends N
? Array<T>
: `${N}` extends `-${string}`
? Array<T>
: `${N}` extends `${string}.${string}`
? Array<T>
: BuildTupleUnchecked<T, N, []>
: never;
}