From deeef5d8f395d2f95e388296faf060da311ccec8 Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Fri, 23 Aug 2019 15:02:06 -0700 Subject: [PATCH 1/2] Better typings for Promise executor, like #31117 --- src/lib/es2015.promise.d.ts | 2 +- src/lib/es5.d.ts | 2 +- .../reference/asyncAwaitNestedClasses_es5.types | 6 +++--- .../asyncFunctionDeclaration15_es5.errors.txt | 4 ++-- .../reference/asyncImportedPromise_es5.types | 2 +- .../reference/asyncImportedPromise_es6.types | 2 +- .../reference/asyncQualifiedReturnType_es5.types | 2 +- .../reference/asyncQualifiedReturnType_es6.types | 2 +- ...ntextuallyTypeAsyncFunctionAwaitOperand.types | 6 +++--- ...contextuallyTypeAsyncFunctionReturnType.types | 12 ++++++------ tests/baselines/reference/inferenceLimit.types | 6 +++--- .../reference/user/chrome-devtools-frontend.log | 16 ++++++++++++++-- tests/baselines/reference/user/fp-ts.log | 12 ++++++++++++ 13 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 tests/baselines/reference/user/fp-ts.log diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index 45b0fa5dc59d9..e440661ecf785 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 8893a7b0bb63e..2460cb2ce7c33 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1378,7 +1378,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 7e3595ec6f4e0..c0b3b9e7493e8 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt @@ -5,7 +5,7 @@ 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. - Construct signature return types 'Thenable' and 'PromiseLike' are incompatible. + Construct signature return types 'Thenable' and 'PromiseLike ? U : T>' are incompatible. The types returned by 'then(...)' are incompatible between these types. 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. @@ -37,7 +37,7 @@ 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: Construct signature return types 'Thenable' and 'PromiseLike' are incompatible. +!!! error TS1055: Construct signature return types 'Thenable' and 'PromiseLike ? U : T>' are incompatible. !!! error TS1055: The types returned by 'then(...)' are incompatible between these types. !!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. async function fn7() { return; } // 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 fc2836e6dea9c..6bbb8dd3d44a2 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/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 0a62d4af67571..6b8b81c905daa 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -8326,6 +8326,11 @@ node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(85 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. node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(161,40): error TS2339: Property 'keysArray' does not exist on type 'Map any>'. 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. +node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(250,5): error TS2322: Type 'Promise ? U : T>' is not assignable to type 'Promise'. + Type 'T extends PromiseLike ? U : T' is not assignable to type 'T'. + 'T extends PromiseLike ? U : T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + Type 'unknown' is not assignable to type 'T'. + 'unknown' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. 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. node_modules/chrome-devtools-frontend/front_end/profiler/HeapSnapshotProxy.js(284,16): error TS2555: Expected at least 2 arguments, but got 1. 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 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. node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(378,39): error TS1110: Type expected. node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(379,31): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. +node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(384,5): error TS2322: Type 'Promise ? U : T>' is not assignable to type 'Promise'. + Type 'T extends PromiseLike ? U : T' is not assignable to type 'T'. + 'T extends PromiseLike ? U : T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + Type 'unknown' is not assignable to type 'T'. + 'unknown' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(420,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RemoteObject.js(422,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. 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) 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. 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'? 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'? +node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(25,3): error TS2322: Type 'Promise' is not assignable to type 'Promise'. + Type 'unknown' is not assignable to type 'undefined'. 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'? 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'? 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 node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1911,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1912,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1913,22): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. -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 HTMLImageElement>'. - Property 'then' is missing in type 'HTMLImageElement' but required in type 'PromiseLike HTMLImageElement>'. +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'. + Type 'HTMLImageElement' provides no match for the signature 'new (width?: number, height?: number): HTMLImageElement'. 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. node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1966,23): error TS2339: Property 'type' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/ui/UIUtils.js(1967,23): error TS2339: Property 'style' does not exist on type 'Element'. diff --git a/tests/baselines/reference/user/fp-ts.log b/tests/baselines/reference/user/fp-ts.log new file mode 100644 index 0000000000000..6dfb48f8d9ff2 --- /dev/null +++ b/tests/baselines/reference/user/fp-ts.log @@ -0,0 +1,12 @@ +Exit Code: 1 +Standard output: +src/Task.ts(78,5): error TS2322: Type 'Promise ? U : A>' is not assignable to type 'Promise'. + Type 'A extends PromiseLike ? U : A' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. +test/Task.ts(9,3): error TS2322: Type 'Promise ? U : A>' is not assignable to type 'Promise'. + Type 'A extends PromiseLike ? U : A' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. + + + +Standard error: From f8859712ce4e2a0c7a7466c33ea67594dc775502 Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Fri, 30 Aug 2019 09:25:12 -0700 Subject: [PATCH 2/2] Add tests --- tests/baselines/reference/promiseType.js | 9 +++++++++ tests/baselines/reference/promiseType.symbols | 15 +++++++++++++++ tests/baselines/reference/promiseType.types | 16 ++++++++++++++++ tests/cases/compiler/promiseType.ts | 6 ++++++ 4 files changed, 46 insertions(+) diff --git a/tests/baselines/reference/promiseType.js b/tests/baselines/reference/promiseType.js index 84d9d713b4810..caf493d4649c8 100644 --- a/tests/baselines/reference/promiseType.js +++ b/tests/baselines/reference/promiseType.js @@ -217,6 +217,12 @@ const pc6 = p.then(() => Promise.reject("1"), () => {}); const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); + +// #27711 + +const expected: Promise = new Promise>(() => {}); + +new Promise(undefined as (resolve: (value: Promise | number) => void) => void); //// [promiseType.js] @@ -440,3 +446,6 @@ const pc6 = p.then(() => Promise.reject("1"), () => { }); const pc7 = p.then(() => Promise.reject("1"), () => { throw 1; }); const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); +// #27711 +const expected = new Promise(() => { }); +new Promise(undefined); diff --git a/tests/baselines/reference/promiseType.symbols b/tests/baselines/reference/promiseType.symbols index cec81cd7d8266..519f5bbb922f3 100644 --- a/tests/baselines/reference/promiseType.symbols +++ b/tests/baselines/reference/promiseType.symbols @@ -1089,3 +1089,18 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) +// #27711 + +const expected: Promise = new Promise>(() => {}); +>expected : Symbol(expected, Decl(promiseType.ts, 221, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +new Promise(undefined as (resolve: (value: Promise | number) => void) => void); +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>undefined : Symbol(undefined) +>resolve : Symbol(resolve, Decl(promiseType.ts, 223, 26)) +>value : Symbol(value, Decl(promiseType.ts, 223, 36)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + diff --git a/tests/baselines/reference/promiseType.types b/tests/baselines/reference/promiseType.types index dd20fb656ea5a..9197aa706057c 100644 --- a/tests/baselines/reference/promiseType.types +++ b/tests/baselines/reference/promiseType.types @@ -1583,3 +1583,19 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >reject : (reason?: any) => Promise >1 : 1 +// #27711 + +const expected: Promise = new Promise>(() => {}); +>expected : Promise +>new Promise>(() => {}) : Promise +>Promise : PromiseConstructor +>() => {} : () => void + +new Promise(undefined as (resolve: (value: Promise | number) => void) => void); +>new Promise(undefined as (resolve: (value: Promise | number) => void) => void) : Promise +>Promise : PromiseConstructor +>undefined as (resolve: (value: Promise | number) => void) => void : (resolve: (value: number | Promise) => void) => void +>undefined : undefined +>resolve : (value: number | Promise) => void +>value : number | Promise + diff --git a/tests/cases/compiler/promiseType.ts b/tests/cases/compiler/promiseType.ts index ba4a7f6041396..f556d1d42db9c 100644 --- a/tests/cases/compiler/promiseType.ts +++ b/tests/cases/compiler/promiseType.ts @@ -217,3 +217,9 @@ const pc6 = p.then(() => Promise.reject("1"), () => {}); const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); + +// #27711 + +const expected: Promise = new Promise>(() => {}); + +new Promise(undefined as (resolve: (value: Promise | number) => void) => void);