-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Type corrections for Promise to adhere to Promises/A+ standard #8216
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
Conversation
Extend definition of the `onfulfilled` handler for the `PromiseLike` interface
Extend definiton for interface `Promise`: take into account that `onfulfilled` is undefined
|
Hi @TorstenStueber, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! TTYL, MSBOT; |
|
@TorstenStueber, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
|
Obviously CI checks have failed. However, in view of the log message I cannot trace the failed tests back to my changes. I would be thankful for any help. |
|
@rbuckton can you take a look. |
|
the tests are failing and you need to accept the new baselines. |
|
I'm just curious, what type of code will this enable/fix? From the signatures it almost looks like this is going to require continual casting or explicit annotations as you change the return type while chaining promises. For example, would this still work? Promise.resolve(42).then(num => {
return "string";
}).then(str => {
return [str];
}).then(arr => {
console.log(arr[0].toLowerCase());
}); |
|
@TorstenStueber Unfortunately the typings for The recent additions to the compiler to support non-nullable types would likely be better for your purposes: then<TResult>(onfulfilled: null | undefined, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>; Also be aware that the interface definition for |
|
@rbuckton Thanks for your great comment. It just dawned to me this morning as well that one should distinguish between a Indeed, according to Promises/A+ the return value of
So out of logic necessity of the Promises/A+ spec and in order to avoid unnecessary type castings I would like to go ahead and change the PR accordingly. About |
Revert changes in PromiseLike interface
Corrections to return type of `then` method in `Promise` interface.
|
Keep in mind the Promise/A+ term "thenable" does not mean it's a Promise or "Promise-like", it just means that it is a foreign object with a callable "then" member. |
|
Just FYI - |
|
@Arnavion You are right, I should have referred to the ES2015 Promise spec instead of Promises/A+. However, my changes are also required by ES2015 Promises:
|
| then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>; | ||
| then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>; | ||
| then<TResult>(onfulfilled?: null | undefined, onrejected?: null | undefined): Promise<T>; | ||
| then<TResult>(onfulfilled?: null | undefined, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T|TResult>; |
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.
this should not be not optional, do not think this would compile this way anyways.
|
With the recent updates to the library including #10448, i do not think this is needed. closing. |
The type definition for promises need to be changed in two ways in order to adhere to the Promises A+ specification:
thenmust bePromiseLike<T|U>(forPromiseLike) andPromise<T|U>(forPromise), respectively. This is due to rule 2.2.7.3 in the spec: if the argumentonfulfilledofthenis not defined, then the promise returned bythenmust be fulfilled with the same value as the originating promise – however, this value is of typeT.valueof the argumentonfulfilledofthenin the interfacePromiseLikemust beT | PromiseLike<T>instead ofT. This is partially due to rule 2.3.3.3.1 of the spec: the valueycan be of typeT | PromiseLike<T>instead ofTonly. Unfortunately, rule 2.3.3.3.1 and the entire Promises A+ standard does not explicitely state thatyis also allowed to be aPromiseLike<T>. However, the Promises/A+ Compliance Test Suite will fail ifyis assumed to be only of typeTand notT | PromiseLike<T>(see test case 'yis a thenable' in https://github.com/promises-aplus/promises-tests/blob/master/lib/tests/2.3.3.js).Remark: the type of
valueof the argumentonfulfilledofthenin the classPromisemust be onlyT, though.For references see my repository, an implementation of the Promises A+ spec in TypeScript – in this project
Promiseis namedTomiseandPromiseLikeis referred to asThenable.Fixes #