-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Better typings for Promise, like #31117 #33707
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -200,18 +200,18 @@ interface PromiseConstructor { | |||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @param values An iterable of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; | ||||||
all<TAll>(values: Iterable<TAll>): Promise<(TAll extends undefined ? TAll : TAll extends PromiseLike<infer UAll> ? UAll : TAll)[]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved | ||||||
* or rejected. | ||||||
* @param values An array of Promises. | ||||||
* @param values An iterable of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
race<T>(values: Iterable<T | PromiseLike<T>>): Promise<T>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You removed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It existed here so that you could include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm happy to fix that but just wondering, is it better to be able to include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I get it now: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✔️ Done. |
||||||
race<T>(values: Iterable<T>): Promise<T extends undefined ? T : T extends PromiseLike<infer U> ? U : T>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
declare namespace Reflect { | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,3 +1,8 @@ | ||||||
// The undefined case is for strictNullChecks false, in which case | ||||||
// undefined extends PromiseLike<infer U> is true, which would otherwise | ||||||
// make Awaited<undefined> -> unknown. | ||||||
type Awaited<T> = T extends undefined ? T : T extends PromiseLike<infer U> ? U : T; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The primary reason we have not introduced this type to this point is that it does not accurately represent the recursive nature of This also has a problem in that it incorrectly handles "thenables" (i.e. objects with a callable "then" member that are not promises): type X = Awaited<{ then(): void }>; // X is `{ then(): void }` In reality, awaiting an object like this will produce a Promise that never resolves. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A problem with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still possible to write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think of a solution like the one in #31117 in the mean time? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
interface PromiseConstructor { | ||||||
/** | ||||||
* A reference to the prototype. | ||||||
|
@@ -18,95 +23,15 @@ interface PromiseConstructor { | |||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5, T6, T7, T8>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5, T6, T7>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5, T6>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4, T5>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>]): Promise<[T1, T2, T3, T4]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2, T3>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises | ||||||
* resolve, or rejected when any Promise is rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
all<T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>; | ||||||
all<T extends readonly any[]>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given this overload, are the tuple-based overloads even necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right! I've now updated this PR accordingly. Thank you! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the trick described in DefinitelyTyped/DefinitelyTyped#41098, this should probably be:
Suggested change
|
||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved | ||||||
* or rejected. | ||||||
* @param values An array of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
race<T>(values: readonly T[]): Promise<T extends PromiseLike<infer U> ? U : T>; | ||||||
|
||||||
/** | ||||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved | ||||||
* or rejected. | ||||||
* @param values An iterable of Promises. | ||||||
* @returns A new Promise. | ||||||
*/ | ||||||
race<T>(values: Iterable<T>): Promise<T extends PromiseLike<infer U> ? U : T>; | ||||||
race<T extends readonly any[]>(values: T): Promise<Awaited<T[number]>>; | ||||||
|
||||||
/** | ||||||
* Creates a new rejected promise for the provided reason. | ||||||
|
@@ -123,7 +48,7 @@ interface PromiseConstructor { | |||||
resolve<T>(value: T | PromiseLike<T>): Promise<T>; | ||||||
|
||||||
/** | ||||||
* Creates a new resolved promise . | ||||||
* Creates a new resolved promise. | ||||||
* @returns A resolved promise. | ||||||
*/ | ||||||
resolve(): Promise<void>; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.