From 1f6d5271fefbf2a56c55e2a8d834ba837e4efa0a Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Fri, 23 Aug 2019 15:02:06 -0700 Subject: [PATCH] Better typings for Promise executor, like #31117 --- src/lib/es2015.promise.d.ts | 2 +- src/lib/es5.d.ts | 2 +- .../asyncAwaitNestedClasses_es5.types | 6 ++--- .../asyncFunctionDeclaration15_es5.errors.txt | 8 +++---- .../reference/asyncImportedPromise_es5.types | 2 +- .../reference/asyncImportedPromise_es6.types | 2 +- .../asyncQualifiedReturnType_es5.types | 2 +- .../asyncQualifiedReturnType_es6.types | 2 +- ...xtuallyTypeAsyncFunctionAwaitOperand.types | 6 ++--- ...textuallyTypeAsyncFunctionReturnType.types | 12 +++++----- .../baselines/reference/inferenceLimit.types | 6 ++--- .../initial-build/resolves-correctly.js | 24 +++++++++---------- 12 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index 83776137c33c1..72ebe87ba07d8 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -10,7 +10,7 @@ interface PromiseConstructor { * a resolve callback used to resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; + new (executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void): Promise ? U : T>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 3eced36c0778d..5e7d32af126e4 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1361,7 +1361,7 @@ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) declare type MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void; declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void; -declare type PromiseConstructorLike = new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseLike; +declare type PromiseConstructorLike = new (executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void) => PromiseLike ? U : T>; interface PromiseLike { /** diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.types b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types index 40f0e5ce9b900..ceba067940be1 100644 --- a/tests/baselines/reference/asyncAwaitNestedClasses_es5.types +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types @@ -14,10 +14,10 @@ class A { return new Promise((resolve) => { resolve(null); }); >new Promise((resolve) => { resolve(null); }) : Promise >Promise : PromiseConstructor ->(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike) => void) => void ->resolve : (value?: void | PromiseLike) => void +>(resolve) => { resolve(null); } : (resolve: (value?: void) => void) => void +>resolve : (value?: void) => void >resolve(null) : void ->resolve : (value?: void | PromiseLike) => void +>resolve : (value?: void) => void >null : null } static C = class C { diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt index 6b4b0a71c6fe1..922bfdbfd9654 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt @@ -5,9 +5,9 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 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. 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. 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. - Type 'Thenable' is not assignable to type 'PromiseLike'. + Type 'Thenable' is not assignable to type 'PromiseLike ? U : T>'. Types of property 'then' are incompatible. - Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. + Type '() => void' is not assignable to type ' ? U : T, TResult2 = never>(onfulfilled?: (value: T extends PromiseLike ? U : T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. Type 'void' is not assignable to type 'PromiseLike'. 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. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. @@ -38,9 +38,9 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 async function fn6(): Thenable { } // error ~~~~~~~~ !!! 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. -!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike'. +!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike ? U : T>'. !!! error TS1055: Types of property 'then' are incompatible. -!!! error TS1055: Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. +!!! error TS1055: Type '() => void' is not assignable to type ' ? U : T, TResult2 = never>(onfulfilled?: (value: T extends PromiseLike ? U : T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. !!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. async function fn7() { return; } // valid: Promise async function fn8() { return 1; } // valid: Promise diff --git a/tests/baselines/reference/asyncImportedPromise_es5.types b/tests/baselines/reference/asyncImportedPromise_es5.types index c8ea6bdf61e5d..809b0370b3cf1 100644 --- a/tests/baselines/reference/asyncImportedPromise_es5.types +++ b/tests/baselines/reference/asyncImportedPromise_es5.types @@ -1,7 +1,7 @@ === tests/cases/conformance/async/es5/task.ts === export class Task extends Promise { } >Task : Task ->Promise : Promise +>Promise : Promise ? U : T> === tests/cases/conformance/async/es5/test.ts === import { Task } from "./task"; diff --git a/tests/baselines/reference/asyncImportedPromise_es6.types b/tests/baselines/reference/asyncImportedPromise_es6.types index 05411f1dda588..c32f669665337 100644 --- a/tests/baselines/reference/asyncImportedPromise_es6.types +++ b/tests/baselines/reference/asyncImportedPromise_es6.types @@ -1,7 +1,7 @@ === tests/cases/conformance/async/es6/task.ts === export class Task extends Promise { } >Task : Task ->Promise : Promise +>Promise : Promise ? U : T> === tests/cases/conformance/async/es6/test.ts === import { Task } from "./task"; diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es5.types b/tests/baselines/reference/asyncQualifiedReturnType_es5.types index 8df2ac42c50c9..9fcfdbba2d63a 100644 --- a/tests/baselines/reference/asyncQualifiedReturnType_es5.types +++ b/tests/baselines/reference/asyncQualifiedReturnType_es5.types @@ -4,7 +4,7 @@ namespace X { export class MyPromise extends Promise { >MyPromise : MyPromise ->Promise : Promise +>Promise : Promise ? U : T> } } diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es6.types b/tests/baselines/reference/asyncQualifiedReturnType_es6.types index f1878fed5d80f..a69b7cc0476a0 100644 --- a/tests/baselines/reference/asyncQualifiedReturnType_es6.types +++ b/tests/baselines/reference/asyncQualifiedReturnType_es6.types @@ -4,7 +4,7 @@ namespace X { export class MyPromise extends Promise { >MyPromise : MyPromise ->Promise : Promise +>Promise : Promise ? U : T> } } diff --git a/tests/baselines/reference/contextuallyTypeAsyncFunctionAwaitOperand.types b/tests/baselines/reference/contextuallyTypeAsyncFunctionAwaitOperand.types index 377f7c15ae321..2b8f7e79fcbca 100644 --- a/tests/baselines/reference/contextuallyTypeAsyncFunctionAwaitOperand.types +++ b/tests/baselines/reference/contextuallyTypeAsyncFunctionAwaitOperand.types @@ -17,10 +17,10 @@ async function fn1(): Promise { >await new Promise(resolve => resolve({ key: "value" })) : Obj >new Promise(resolve => resolve({ key: "value" })) : Promise >Promise : PromiseConstructor ->resolve => resolve({ key: "value" }) : (resolve: (value?: Obj | PromiseLike) => void) => void ->resolve : (value?: Obj | PromiseLike) => void +>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj) => void) => void +>resolve : (value?: Obj) => void >resolve({ key: "value" }) : void ->resolve : (value?: Obj | PromiseLike) => void +>resolve : (value?: Obj) => void >{ key: "value" } : { key: "value"; } >key : "value" >"value" : "value" diff --git a/tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types b/tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types index d47a623ffc6c3..f9462634dcec0 100644 --- a/tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types +++ b/tests/baselines/reference/contextuallyTypeAsyncFunctionReturnType.types @@ -17,12 +17,12 @@ async function fn2(): Promise { return new Promise(resolve => { >new Promise(resolve => { resolve({ key: "value" }); }) : Promise >Promise : PromiseConstructor ->resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike) => void) => void ->resolve : (value?: Obj | PromiseLike) => void +>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj) => void) => void +>resolve : (value?: Obj) => void resolve({ key: "value" }); >resolve({ key: "value" }) : void ->resolve : (value?: Obj | PromiseLike) => void +>resolve : (value?: Obj) => void >{ key: "value" } : { key: "value"; } >key : "value" >"value" : "value" @@ -47,12 +47,12 @@ async function fn4(): Promise { >await new Promise(resolve => { resolve({ key: "value" }); }) : Obj >new Promise(resolve => { resolve({ key: "value" }); }) : Promise >Promise : PromiseConstructor ->resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike) => void) => void ->resolve : (value?: Obj | PromiseLike) => void +>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj) => void) => void +>resolve : (value?: Obj) => void resolve({ key: "value" }); >resolve({ key: "value" }) : void ->resolve : (value?: Obj | PromiseLike) => void +>resolve : (value?: Obj) => void >{ key: "value" } : { key: "value"; } >key : "value" >"value" : "value" diff --git a/tests/baselines/reference/inferenceLimit.types b/tests/baselines/reference/inferenceLimit.types index 6aa7ab501ea16..3b6973bc9030f 100644 --- a/tests/baselines/reference/inferenceLimit.types +++ b/tests/baselines/reference/inferenceLimit.types @@ -19,8 +19,8 @@ export class BrokenClass { >new Promise>((resolve, reject) => { let result: Array = []; 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) => { resolve(orders); }); }) : Promise >Promise : PromiseConstructor >MyModule : any ->(resolve, reject) => { let result: Array = []; 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) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[] | PromiseLike) => void, reject: (reason?: any) => void) => Promise ->resolve : (value?: MyModule.MyModel[] | PromiseLike) => void +>(resolve, reject) => { let result: Array = []; 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) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[]) => void, reject: (reason?: any) => void) => Promise +>resolve : (value?: MyModule.MyModel[]) => void >reject : (reason?: any) => void let result: Array = []; @@ -93,7 +93,7 @@ export class BrokenClass { resolve(orders); >resolve(orders) : void ->resolve : (value?: MyModule.MyModel[] | PromiseLike) => void +>resolve : (value?: MyModule.MyModel[]) => void >orders : MyModule.MyModel[] }); diff --git a/tests/baselines/reference/tsbuild/moduleSpecifiers/initial-build/resolves-correctly.js b/tests/baselines/reference/tsbuild/moduleSpecifiers/initial-build/resolves-correctly.js index 2ba8fa808170b..60a205d566c94 100644 --- a/tests/baselines/reference/tsbuild/moduleSpecifiers/initial-build/resolves-correctly.js +++ b/tests/baselines/reference/tsbuild/moduleSpecifiers/initial-build/resolves-correctly.js @@ -14,8 +14,8 @@ exports.__esModule = true; "program": { "fileInfos": { "../../../.ts/lib.es5.d.ts": { - "version": "406734842058", - "signature": "406734842058" + "version": "-669426501472", + "signature": "-669426501472" }, "../../../.ts/lib.es2015.d.ts": { "version": "57263133672", @@ -42,8 +42,8 @@ exports.__esModule = true; "signature": "232404497324" }, "../../../.ts/lib.es2015.promise.d.ts": { - "version": "235321148269", - "signature": "235321148269" + "version": "17314103363", + "signature": "17314103363" }, "../../../.ts/lib.es2015.proxy.d.ts": { "version": "55479865087", @@ -114,8 +114,8 @@ exports.__esModule = true; "program": { "fileInfos": { "../../../.ts/lib.es5.d.ts": { - "version": "406734842058", - "signature": "406734842058" + "version": "-669426501472", + "signature": "-669426501472" }, "../../../.ts/lib.es2015.d.ts": { "version": "57263133672", @@ -142,8 +142,8 @@ exports.__esModule = true; "signature": "232404497324" }, "../../../.ts/lib.es2015.promise.d.ts": { - "version": "235321148269", - "signature": "235321148269" + "version": "17314103363", + "signature": "17314103363" }, "../../../.ts/lib.es2015.proxy.d.ts": { "version": "55479865087", @@ -237,8 +237,8 @@ exports.getVar = getVar; "program": { "fileInfos": { "../../../.ts/lib.es5.d.ts": { - "version": "406734842058", - "signature": "406734842058" + "version": "-669426501472", + "signature": "-669426501472" }, "../../../.ts/lib.es2015.d.ts": { "version": "57263133672", @@ -265,8 +265,8 @@ exports.getVar = getVar; "signature": "232404497324" }, "../../../.ts/lib.es2015.promise.d.ts": { - "version": "235321148269", - "signature": "235321148269" + "version": "17314103363", + "signature": "17314103363" }, "../../../.ts/lib.es2015.proxy.d.ts": { "version": "55479865087",