[@types/when] Fix when.js then() when TResult is a subtype of T (#25110)

* Fix when.js then() when TResult is a subtype of T

Change the order of .then overrides to deprioritize no generics.

* Move the more specific overload to the top
This commit is contained in:
Su-Shing Chen 2018-04-25 12:20:45 +12:00 committed by Wesley Wigham
parent 211a5eb474
commit 8d87c67236
3 changed files with 36 additions and 9 deletions

16
types/when/index.d.ts vendored
View File

@ -285,11 +285,11 @@ declare namespace When {
// be a constructor with prototype set to an instance of Error.
otherwise<U>(exceptionType: any, onRejected?: (reason: any) => U | Promise<U>): Promise<U>;
then(
onFulfilled?: ((value: T) => T | Thenable<T>) | undefined | null,
onRejected?: ((reason: any) => T | Thenable<T>) | undefined | null,
then<TResult1, TResult2>(
onFulfilled: ((value: T) => TResult1 | Thenable<TResult1>),
onRejected: ((reason: any) => TResult2 | Thenable<TResult2>),
onProgress?: (update: any) => void
): Promise<T>;
): Promise<TResult1 | TResult2>;
then<TResult>(
onFulfilled: ((value: T) => TResult | Thenable<TResult>),
onRejected?: ((reason: any) => TResult | Thenable<TResult>) | undefined | null,
@ -300,11 +300,11 @@ declare namespace When {
onRejected: ((reason: any) => TResult | Thenable<TResult>),
onProgress?: (update: any) => void
): Promise<T | TResult>;
then<TResult1, TResult2>(
onFulfilled: ((value: T) => TResult1 | Thenable<TResult1>),
onRejected: ((reason: any) => TResult2 | Thenable<TResult2>),
then(
onFulfilled?: ((value: T) => T | Thenable<T>) | undefined | null,
onRejected?: ((reason: any) => T | Thenable<T>) | undefined | null,
onProgress?: (update: any) => void
): Promise<TResult1 | TResult2>;
): Promise<T>;
spread<T>(onFulfilled: _.Fn0<Promise<T> | T>): Promise<T>;
spread<A1, T>(onFulfilled: _.Fn1<A1, Promise<T> | T>): Promise<T>;

View File

@ -1,6 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"lib": [
"es6"
],

View File

@ -14,9 +14,24 @@ class ForeignPromise<T> {
then(onFulfilled?: (value: T) => T, onRejected?: (reason: any) => T): ForeignPromise<T> {
return new ForeignPromise(onFulfilled ? onFulfilled(this.value) : this.value);
}
};
}
interface IData {
timestamp: number;
}
class Data implements IData {
timestamp: number;
date: Date;
constructor({ timestamp }: IData) {
this.timestamp = timestamp;
this.date = new Date(timestamp);
}
}
var promise: when.Promise<number>;
var promise2: when.Promise<Data>;
var foreign = new ForeignPromise<number>(1);
var error = new Error("boom!");
var example: () => void;
@ -222,6 +237,17 @@ promise = when(1).then(undefined, (err: any) => 2);
promise = when(1).then((val: number) => val + val, (err: any) => 2);
promise = when(1).then((val: number) => when(val + val), (err: any) => 2);
promise = when('1').then((val: string) => parseInt(val));
// Tests for when TResult is a subtype of T
const subData: IData = { timestamp: Date.now() };
const errorData: Data = new Data({ timestamp: -1 });
promise2 = when(subData).then((val: IData) => new Data(val));
promise2 = when(subData).then((val: IData) => when(new Data(val)));
promise2 = when(subData).then((val: IData) => new Data(val), (err: any) => errorData);
promise2 = when(subData).then((val: IData) => when(new Data(val)), (err: any) => errorData);
/* promise.spread(onFulfilledArray) */
promise = when([]).spread(() => 2);