Inconsistent type on `Thenable.then` overload?
Author: LucretielCreated May 13, 2019Updated May 13, 2019
One of the overloads for Thenable.then is:
then <U> (
onFulfilled?: (value: R) => U | Thenable<U>,
onRejected?: (error: any) => void,
): Thenable<U>;However, consider this example:
let promise = Promise<number>.reject(new Error("error"));
let newPromise = promise.then(
(value: number): string => value.toString(),
(error: any): void => { console.log(error); },
);The type of newPromise, based on the overload, is Promise<string>. However, because the onRejected function doesn't throw or return a rejected promise, newPromise becomes a resolved promise with the return value of onRejected, which is void, which means that newPromise should be Promise<T | void>. Specifically, this code should not compile:
newPromise.then((value: string) => {
// value should be `(string | void)`, since it could have a
//value from the `onRejected` branch
});Source: stefanpenner/es6-promise