From d73f413fb66639480b96d9031df9727ed61fcd81 Mon Sep 17 00:00:00 2001 From: Retsam Date: Wed, 13 Dec 2017 14:02:42 -0500 Subject: [PATCH] Fix inferred types for targetted error handlers The typings for targetted catch statements don't infer properly with Error constructors, for example with `.catch(SomeErrorSubtype, (e) => /*...*/)`, `e` is inferred to be the constructor of SomeErrorSubtype, not an instance of SomeErrorSubtype, so this must be explicitly typed as `.catch(SomeErrorSubtype, (e: SomeErrorSubtype) => /*...*/)` for the typings to be accurate. The root causes is that it is erroneously falling into the wrong overload, the overload that accepts arbitrary objects as the first argument to .catch. This fix requires loosening the restriction that SomeErrorSubtype must be a subtype of Error, but otherwise preserves existing behavior. Also, makes a utility type to reduce some of the boilerplate. --- types/bluebird/index.d.ts | 123 ++++++++++---------------------------- 1 file changed, 33 insertions(+), 90 deletions(-) diff --git a/types/bluebird/index.d.ts b/types/bluebird/index.d.ts index 9c68e85212..b28f821e12 100644 --- a/types/bluebird/index.d.ts +++ b/types/bluebird/index.d.ts @@ -35,6 +35,8 @@ * THE SOFTWARE. */ +type CatchFilter = (new (...args: any[]) => E) | ((error: E) => boolean) | (object & E); + declare class Bluebird implements PromiseLike, Bluebird.Inspection { /** * Create a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise. @@ -77,128 +79,69 @@ declare class Bluebird implements PromiseLike, Bluebird.Inspection { * * Alias `.caught();` for compatibility with earlier ECMAScript version. */ - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - filter4: (new (...args: any[]) => E4), - filter5: (new (...args: any[]) => E5), - onReject: (error: E1 | E2 | E3 | E4 | E5) => R | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), - filter4: ((error: E4) => boolean) | (E4 & object), - filter5: ((error: E5) => boolean) | (E5 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, + filter4: CatchFilter, + filter5: CatchFilter, onReject: (error: E1 | E2 | E3 | E4 | E5) => R | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - filter4: (new (...args: any[]) => E4), - filter5: (new (...args: any[]) => E5), - onReject: (error: E1 | E2 | E3 | E4 | E5) => U | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), - filter4: ((error: E4) => boolean) | (E4 & object), - filter5: ((error: E5) => boolean) | (E5 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, + filter4: CatchFilter, + filter5: CatchFilter, onReject: (error: E1 | E2 | E3 | E4 | E5) => U | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - filter4: (new (...args: any[]) => E4), - onReject: (error: E1 | E2 | E3 | E4) => R | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), - filter4: ((error: E4) => boolean) | (E4 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, + filter4: CatchFilter, onReject: (error: E1 | E2 | E3 | E4) => R | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - filter4: (new (...args: any[]) => E4), - onReject: (error: E1 | E2 | E3 | E4) => U | PromiseLike, - ): Bluebird; + catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), - filter4: ((error: E4) => boolean) | (E4 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, + filter4: CatchFilter, onReject: (error: E1 | E2 | E3 | E4) => U | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - onReject: (error: E1 | E2 | E3) => R | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, onReject: (error: E1 | E2 | E3) => R | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - filter3: (new (...args: any[]) => E3), - onReject: (error: E1 | E2 | E3) => U | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), - filter3: ((error: E3) => boolean) | (E3 & object), + filter1: CatchFilter, + filter2: CatchFilter, + filter3: CatchFilter, onReject: (error: E1 | E2 | E3) => U | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - onReject: (error: E1 | E2) => R | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), + filter1: CatchFilter, + filter2: CatchFilter, onReject: (error: E1 | E2) => R | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - filter2: (new (...args: any[]) => E2), - onReject: (error: E1 | E2) => U | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), - filter2: ((error: E2) => boolean) | (E2 & object), + filter1: CatchFilter, + filter2: CatchFilter, onReject: (error: E1 | E2) => U | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - onReject: (error: E1) => R | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), + filter1: CatchFilter, onReject: (error: E1) => R | PromiseLike, ): Bluebird; - catch( - filter1: (new (...args: any[]) => E1), - onReject: (error: E1) => U | PromiseLike, - ): Bluebird; catch( - filter1: ((error: E1) => boolean) | (E1 & object), + filter1: CatchFilter, onReject: (error: E1) => U | PromiseLike, ): Bluebird;