Skip to content

Commit

Permalink
Better typings for Promise executor, like microsoft#31117
Browse files Browse the repository at this point in the history
  • Loading branch information
jablko committed Aug 27, 2019
1 parent 111b73a commit 1f6d527
Show file tree
Hide file tree
Showing 12 changed files with 37 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/lib/es2015.promise.d.ts
Expand Up @@ -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 <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
new <T>(executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void): Promise<T extends PromiseLike<infer U> ? U : T>;

/**
* Creates a Promise that is resolved with an array of results when all of the provided Promises
Expand Down
2 changes: 1 addition & 1 deletion src/lib/es5.d.ts
Expand Up @@ -1361,7 +1361,7 @@ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol)
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;

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

interface PromiseLike<T> {
/**
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/asyncAwaitNestedClasses_es5.types
Expand Up @@ -14,10 +14,10 @@ class A {
return new Promise((resolve) => { resolve(null); });
>new Promise((resolve) => { resolve(null); }) : Promise<void>
>Promise : PromiseConstructor
>(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike<void>) => void) => void
>resolve : (value?: void | PromiseLike<void>) => void
>(resolve) => { resolve(null); } : (resolve: (value?: void) => void) => void
>resolve : (value?: void) => void
>resolve(null) : void
>resolve : (value?: void | PromiseLike<void>) => void
>resolve : (value?: void) => void
>null : null
}
static C = class C {
Expand Down
Expand Up @@ -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<T>'.
Type 'Thenable' is not assignable to type 'PromiseLike<T extends PromiseLike<infer U> ? U : T>'.
Types of property 'then' are incompatible.
Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
Type '() => void' is not assignable to type '<TResult1 = T extends PromiseLike<infer U> ? U : T, TResult2 = never>(onfulfilled?: (value: T extends PromiseLike<infer U> ? U : T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
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.
Expand Down Expand Up @@ -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<T>'.
!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike<T extends PromiseLike<infer U> ? U : T>'.
!!! error TS1055: Types of property 'then' are incompatible.
!!! error TS1055: Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
!!! error TS1055: Type '() => void' is not assignable to type '<TResult1 = T extends PromiseLike<infer U> ? U : T, TResult2 = never>(onfulfilled?: (value: T extends PromiseLike<infer U> ? U : T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
async function fn7() { return; } // valid: Promise<void>
async function fn8() { return 1; } // valid: Promise<number>
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncImportedPromise_es5.types
@@ -1,7 +1,7 @@
=== tests/cases/conformance/async/es5/task.ts ===
export class Task<T> extends Promise<T> { }
>Task : Task<T>
>Promise : Promise<T>
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>

=== tests/cases/conformance/async/es5/test.ts ===
import { Task } from "./task";
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncImportedPromise_es6.types
@@ -1,7 +1,7 @@
=== tests/cases/conformance/async/es6/task.ts ===
export class Task<T> extends Promise<T> { }
>Task : Task<T>
>Promise : Promise<T>
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>

=== tests/cases/conformance/async/es6/test.ts ===
import { Task } from "./task";
Expand Down
Expand Up @@ -4,7 +4,7 @@ namespace X {

export class MyPromise<T> extends Promise<T> {
>MyPromise : MyPromise<T>
>Promise : Promise<T>
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
}
}

Expand Down
Expand Up @@ -4,7 +4,7 @@ namespace X {

export class MyPromise<T> extends Promise<T> {
>MyPromise : MyPromise<T>
>Promise : Promise<T>
>Promise : Promise<T extends PromiseLike<infer U> ? U : T>
}
}

Expand Down
Expand Up @@ -17,10 +17,10 @@ async function fn1(): Promise<Obj> {
>await new Promise(resolve => resolve({ key: "value" })) : Obj
>new Promise(resolve => resolve({ key: "value" })) : Promise<Obj>
>Promise : PromiseConstructor
>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
>resolve : (value?: Obj | PromiseLike<Obj>) => void
>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj) => void) => void
>resolve : (value?: Obj) => void
>resolve({ key: "value" }) : void
>resolve : (value?: Obj | PromiseLike<Obj>) => void
>resolve : (value?: Obj) => void
>{ key: "value" } : { key: "value"; }
>key : "value"
>"value" : "value"
Expand Down
Expand Up @@ -17,12 +17,12 @@ async function fn2(): Promise<Obj> {
return new Promise(resolve => {
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
>Promise : PromiseConstructor
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
>resolve : (value?: Obj | PromiseLike<Obj>) => 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<Obj>) => void
>resolve : (value?: Obj) => void
>{ key: "value" } : { key: "value"; }
>key : "value"
>"value" : "value"
Expand All @@ -47,12 +47,12 @@ async function fn4(): Promise<Obj> {
>await new Promise(resolve => { resolve({ key: "value" }); }) : Obj
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
>Promise : PromiseConstructor
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
>resolve : (value?: Obj | PromiseLike<Obj>) => 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<Obj>) => void
>resolve : (value?: Obj) => void
>{ key: "value" } : { key: "value"; }
>key : "value"
>"value" : "value"
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/inferenceLimit.types
Expand Up @@ -19,8 +19,8 @@ export class BrokenClass {
>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[]>
>Promise : PromiseConstructor
>MyModule : any
>(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>
>resolve : (value?: MyModule.MyModel[] | PromiseLike<MyModule.MyModel[]>) => void
>(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>
>resolve : (value?: MyModule.MyModel[]) => void
>reject : (reason?: any) => void

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

resolve(orders);
>resolve(orders) : void
>resolve : (value?: MyModule.MyModel[] | PromiseLike<MyModule.MyModel[]>) => void
>resolve : (value?: MyModule.MyModel[]) => void
>orders : MyModule.MyModel[]

});
Expand Down
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down

0 comments on commit 1f6d527

Please sign in to comment.