-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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:
then
must bePromiseLike<T|U>
(forPromiseLike
) andPromise<T|U>
(forPromise
), respectively. This is due to rule 2.2.7.3 in the spec: if the argumentonfulfilled
ofthen
is not defined, then the promise returned bythen
must be fulfilled with the same value as the originating promise – however, this value is of typeT
.value
of the argumentonfulfilled
ofthen
in the interfacePromiseLike
must beT | PromiseLike<T>
instead ofT
. This is partially due to rule 2.3.3.3.1 of the spec: the valuey
can be of typeT | PromiseLike<T>
instead ofT
only. Unfortunately, rule 2.3.3.3.1 and the entire Promises A+ standard does not explicitely state thaty
is also allowed to be aPromiseLike<T>
. However, the Promises/A+ Compliance Test Suite will fail ify
is assumed to be only of typeT
and notT | PromiseLike<T>
(see test case 'y
is a thenable' in https://github.com/promises-aplus/promises-tests/blob/master/lib/tests/2.3.3.js).Remark: the type of
value
of the argumentonfulfilled
ofthen
in the classPromise
must be onlyT
, though.For references see my repository, an implementation of the Promises A+ spec in TypeScript – in this project
Promise
is namedTomise
andPromiseLike
is referred to asThenable
.Fixes #