Skip to content

Commit 25b6543

Browse files
committed
Better typings for Promise executor, like #31117
1 parent 3b919e2 commit 25b6543

13 files changed

+49
-25
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
});

tests/baselines/reference/user/chrome-devtools-frontend.log

+14-2
Original file line numberDiff line numberDiff line change
@@ -8326,6 +8326,11 @@ node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(85
83268326
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(129,14): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
83278327
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(161,40): error TS2339: Property 'keysArray' does not exist on type 'Map<number, (arg0: any) => any>'.
83288328
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(231,15): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
8329+
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(250,5): error TS2322: Type 'Promise<T extends PromiseLike<infer U> ? U : T>' is not assignable to type 'Promise<T>'.
8330+
Type 'T extends PromiseLike<infer U> ? U : T' is not assignable to type 'T'.
8331+
'T extends PromiseLike<infer U> ? U : T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
8332+
Type 'unknown' is not assignable to type 'T'.
8333+
'unknown' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
83298334
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(263,14): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
83308335
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(284,16): error TS2555: Expected at least 2 arguments, but got 1.
83318336
node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(286,43): error TS2555: Expected at least 4 arguments, but got 3.
@@ -9617,6 +9622,11 @@ node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(370,31): err
96179622
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(371,14): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
96189623
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(378,39): error TS1110: Type expected.
96199624
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(379,31): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'.
9625+
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(384,5): error TS2322: Type 'Promise<T extends PromiseLike<infer U> ? U : T>' is not assignable to type 'Promise<T>'.
9626+
Type 'T extends PromiseLike<infer U> ? U : T' is not assignable to type 'T'.
9627+
'T extends PromiseLike<infer U> ? U : T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
9628+
Type 'unknown' is not assignable to type 'T'.
9629+
'unknown' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
96209630
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(420,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'.
96219631
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(422,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'.
96229632
node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(423,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'.
@@ -10930,6 +10940,8 @@ node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(12,64)
1093010940
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(12,94): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
1093110941
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(13,6): error TS2551: Property 'testRunner' does not exist on type 'Window & typeof globalThis'. Did you mean 'TestRunner'?
1093210942
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(24,8): error TS2551: Property 'testRunner' does not exist on type 'Window & typeof globalThis'. Did you mean 'TestRunner'?
10943+
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(25,3): error TS2322: Type 'Promise<unknown>' is not assignable to type 'Promise<undefined>'.
10944+
Type 'unknown' is not assignable to type 'undefined'.
1093310945
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(42,21): error TS2551: Property 'testRunner' does not exist on type 'Window & typeof globalThis'. Did you mean 'TestRunner'?
1093410946
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(76,8): error TS2551: Property 'testRunner' does not exist on type 'Window & typeof globalThis'. Did you mean 'TestRunner'?
1093510947
node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(117,19): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
@@ -12649,8 +12661,8 @@ node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1910,22): error TS
1264912661
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1911,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'.
1265012662
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1912,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'.
1265112663
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1913,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'.
12652-
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1943,50): error TS2345: Argument of type 'HTMLImageElement' is not assignable to parameter of type '(new (width?: number, height?: number) => HTMLImageElement) | PromiseLike<new (width?: number, height?: number) => HTMLImageElement>'.
12653-
Property 'then' is missing in type 'HTMLImageElement' but required in type 'PromiseLike<new (width?: number, height?: number) => HTMLImageElement>'.
12664+
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1943,50): error TS2345: Argument of type 'HTMLImageElement' is not assignable to parameter of type 'new (width?: number, height?: number) => HTMLImageElement'.
12665+
Type 'HTMLImageElement' provides no match for the signature 'new (width?: number, height?: number): HTMLImageElement'.
1265412666
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1961,12): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
1265512667
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1966,23): error TS2339: Property 'type' does not exist on type 'Element'.
1265612668
node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1967,23): error TS2339: Property 'style' does not exist on type 'Element'.
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Exit Code: 1
2+
Standard output:
3+
src/Task.ts(78,5): error TS2322: Type 'Promise<A extends PromiseLike<infer U> ? U : A>' is not assignable to type 'Promise<A>'.
4+
Type 'A extends PromiseLike<infer U> ? U : A' is not assignable to type 'A'.
5+
Type 'unknown' is not assignable to type 'A'.
6+
test/Task.ts(9,3): error TS2322: Type 'Promise<A extends PromiseLike<infer U> ? U : A>' is not assignable to type 'Promise<A>'.
7+
Type 'A extends PromiseLike<infer U> ? U : A' is not assignable to type 'A'.
8+
Type 'unknown' is not assignable to type 'A'.
9+
10+
11+
12+
Standard error:

0 commit comments

Comments
 (0)