Skip to content

Commit 57f9f72

Browse files
committed
Better typings for Promise executor, like #31117
1 parent 27d9dbe commit 57f9f72

11 files changed

+23
-23
lines changed

src/lib/es2015.promise.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface PromiseConstructor {
1010
* a resolve callback used to resolve the promise with a value or the result of another promise,
1111
* and a reject callback used to reject the promise with a provided reason or error.
1212
*/
13-
new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
13+
new <T>(executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void): Promise<T extends PromiseLike<infer U> ? U : T>;
1414

1515
/**
1616
* Creates a Promise that is resolved with an array of results when all of the provided Promises

src/lib/es5.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,7 @@ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol)
13781378
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
13791379
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
13801380

1381-
declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;
1381+
declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void) => PromiseLike<T extends PromiseLike<infer U> ? U : T>;
13821382

13831383
interface PromiseLike<T> {
13841384
/**

tests/baselines/reference/asyncAwaitNestedClasses_es5.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ class A {
1414
return new Promise((resolve) => { resolve(null); });
1515
>new Promise((resolve) => { resolve(null); }) : Promise<void>
1616
>Promise : PromiseConstructor
17-
>(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike<void>) => void) => void
18-
>resolve : (value?: void | PromiseLike<void>) => void
17+
>(resolve) => { resolve(null); } : (resolve: (value?: void) => void) => void
18+
>resolve : (value?: void) => void
1919
>resolve(null) : void
20-
>resolve : (value?: void | PromiseLike<void>) => void
20+
>resolve : (value?: void) => void
2121
>null : null
2222
}
2323
static C = class C {

tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
55
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(8,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
66
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
77
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
8-
Construct signature return types 'Thenable' and 'PromiseLike<T>' are incompatible.
8+
Construct signature return types 'Thenable' and 'PromiseLike<T extends PromiseLike<infer U> ? U : T>' are incompatible.
99
The types returned by 'then(...)' are incompatible between these types.
1010
Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
1111
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member.
@@ -37,7 +37,7 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
3737
async function fn6(): Thenable { } // error
3838
~~~~~~~~
3939
!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
40-
!!! error TS1055: Construct signature return types 'Thenable' and 'PromiseLike<T>' are incompatible.
40+
!!! error TS1055: Construct signature return types 'Thenable' and 'PromiseLike<T extends PromiseLike<infer U> ? U : T>' are incompatible.
4141
!!! error TS1055: The types returned by 'then(...)' are incompatible between these types.
4242
!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
4343
async function fn7() { return; } // valid: Promise<void>

tests/baselines/reference/asyncImportedPromise_es5.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
=== tests/cases/conformance/async/es5/task.ts ===
22
export class Task<T> extends Promise<T> { }
33
>Task : Task<T>
4-
>Promise : Promise<T>
4+
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
55

66
=== tests/cases/conformance/async/es5/test.ts ===
77
import { Task } from "./task";

tests/baselines/reference/asyncImportedPromise_es6.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
=== tests/cases/conformance/async/es6/task.ts ===
22
export class Task<T> extends Promise<T> { }
33
>Task : Task<T>
4-
>Promise : Promise<T>
4+
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
55

66
=== tests/cases/conformance/async/es6/test.ts ===
77
import { Task } from "./task";

tests/baselines/reference/asyncQualifiedReturnType_es5.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace X {
44

55
export class MyPromise<T> extends Promise<T> {
66
>MyPromise : MyPromise<T>
7-
>Promise : Promise<T>
7+
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
88
}
99
}
1010

tests/baselines/reference/asyncQualifiedReturnType_es6.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace X {
44

55
export class MyPromise<T> extends Promise<T> {
66
>MyPromise : MyPromise<T>
7-
>Promise : Promise<T>
7+
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
88
}
99
}
1010

tests/baselines/reference/contextuallyTypeAsyncFunctionAwaitOperand.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ async function fn1(): Promise<Obj> {
1717
>await new Promise(resolve => resolve({ key: "value" })) : Obj
1818
>new Promise(resolve => resolve({ key: "value" })) : Promise<Obj>
1919
>Promise : PromiseConstructor
20-
>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
21-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
20+
>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj) => void) => void
21+
>resolve : (value?: Obj) => void
2222
>resolve({ key: "value" }) : void
23-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
23+
>resolve : (value?: Obj) => void
2424
>{ key: "value" } : { key: "value"; }
2525
>key : "value"
2626
>"value" : "value"

tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ async function fn2(): Promise<Obj> {
1717
return new Promise(resolve => {
1818
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
1919
>Promise : PromiseConstructor
20-
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
21-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
20+
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj) => void) => void
21+
>resolve : (value?: Obj) => void
2222

2323
resolve({ key: "value" });
2424
>resolve({ key: "value" }) : void
25-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
25+
>resolve : (value?: Obj) => void
2626
>{ key: "value" } : { key: "value"; }
2727
>key : "value"
2828
>"value" : "value"
@@ -47,12 +47,12 @@ async function fn4(): Promise<Obj> {
4747
>await new Promise(resolve => { resolve({ key: "value" }); }) : Obj
4848
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
4949
>Promise : PromiseConstructor
50-
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
51-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
50+
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj) => void) => void
51+
>resolve : (value?: Obj) => void
5252

5353
resolve({ key: "value" });
5454
>resolve({ key: "value" }) : void
55-
>resolve : (value?: Obj | PromiseLike<Obj>) => void
55+
>resolve : (value?: Obj) => void
5656
>{ key: "value" } : { key: "value"; }
5757
>key : "value"
5858
>"value" : "value"

tests/baselines/reference/inferenceLimit.types

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export class BrokenClass {
1919
>new Promise<Array<MyModule.MyModel>>((resolve, reject) => { let result: Array<MyModule.MyModel> = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array<MyModule.MyModel>) => { resolve(orders); }); }) : Promise<MyModule.MyModel[]>
2020
>Promise : PromiseConstructor
2121
>MyModule : any
22-
>(resolve, reject) => { let result: Array<MyModule.MyModel> = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array<MyModule.MyModel>) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[] | PromiseLike<MyModule.MyModel[]>) => void, reject: (reason?: any) => void) => Promise<void>
23-
>resolve : (value?: MyModule.MyModel[] | PromiseLike<MyModule.MyModel[]>) => void
22+
>(resolve, reject) => { let result: Array<MyModule.MyModel> = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array<MyModule.MyModel>) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[]) => void, reject: (reason?: any) => void) => Promise<void>
23+
>resolve : (value?: MyModule.MyModel[]) => void
2424
>reject : (reason?: any) => void
2525

2626
let result: Array<MyModule.MyModel> = [];
@@ -93,7 +93,7 @@ export class BrokenClass {
9393

9494
resolve(orders);
9595
>resolve(orders) : void
96-
>resolve : (value?: MyModule.MyModel[] | PromiseLike<MyModule.MyModel[]>) => void
96+
>resolve : (value?: MyModule.MyModel[]) => void
9797
>orders : MyModule.MyModel[]
9898

9999
});

0 commit comments

Comments
 (0)