From 3cf39396301026e5e063080cc36253052db914c5 Mon Sep 17 00:00:00 2001 From: d-ph Date: Sun, 26 Aug 2018 15:20:29 +0100 Subject: [PATCH] [bluebird-global] Miscellaneous improvements 1. Bring copy&pasted code from std lib back to sync. 2. Come up with a plan to remove the copy&paste from std lib 3. Add an information that due to how these typings work, users can't cast instances of global Promise to Bluebird promise. Also, mention a walk-around if that's needed. --- .../bluebird-global/bluebird-global-tests.ts | 8 ++ types/bluebird-global/index.d.ts | 75 ++++++++++++++----- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/types/bluebird-global/bluebird-global-tests.ts b/types/bluebird-global/bluebird-global-tests.ts index b6bbb915e2..3928ba46c9 100644 --- a/types/bluebird-global/bluebird-global-tests.ts +++ b/types/bluebird-global/bluebird-global-tests.ts @@ -44,3 +44,11 @@ function testPromiseRejection() { function testGithubTicket28081Regression() { Promise.resolve([3]).map((n: number) => true); } + +import Bluebird = require("bluebird"); + +function testTheWalkaroundForCastingGlobalPromiseToBluebirdPromise() { + const bluebirdString: Bluebird = Bluebird.resolve( + new Promise(() => 'Lorem ipsum') + ); +} diff --git a/types/bluebird-global/index.d.ts b/types/bluebird-global/index.d.ts index 7f38f981f1..fca3c1235e 100644 --- a/types/bluebird-global/index.d.ts +++ b/types/bluebird-global/index.d.ts @@ -10,6 +10,25 @@ * If you want to leverage the fact, that bluebird polyfills the global Promise in the browser, then * you need to tell TypeScript about this. The following declaration file does exactly that. * + * 1.1. Why you might not want to use `bluebird-global` instead of `bluebird`. + * + * Because of how these typings tell TypeScript about bluebird's Promise methods, it is not + * possible to cast global Promises to Bluebird promises in your code. In other words, you won't + * be able to do the following (even though it's possible at the runtime): + * + * let bluebirdPromise: Bluebird = new Promise(() => { return 'Lorem ipsum'; }); + * + * If you need to, you can walk-around this by constructing a new Bluebird promise over an instance + * of the global Promise, like so: + * + * let bluebirdPromise: Bluebird = Bluebird.resolve( + * new Promise(() => { return 'Lorem ipsum'; }) + * ); + * + * So the bottom line is: if you use these typings, then be mindful when you try to mix the global + * Promises with the Bluebird promises. You can avoid this problem by just settling on using either + * of them and not both of them at the same time. + * * 2. How to use it? * * It should just work, but there are a couple of points to be wary about: @@ -60,6 +79,17 @@ * d. target es6, latest "es20xx", e.g. "es2017" */ +/* + * @todo When dropping TS 2.x support, uncomment the following triple-slash directives and + * remove the copy&paste from this file (marked with #std-lib-copy&paste-to-remove) + * + * TS 2.x support should be dropped once bluebird's typings stop compiling on 2.x (i.e. + * once bluebird's typings stop supporting TS 2.x) + */ +/* /// */ +/* /// */ +/* /// */ + import Bluebird = require("bluebird"); declare global { @@ -73,7 +103,7 @@ declare global { bind: Bluebird["bind"]; call: Bluebird["call"]; cancel: Bluebird["cancel"]; - // catch: Bluebird["catch"]; + // catch: Bluebird["catch"]; // Provided by lib.es5.d.ts caught: Bluebird["caught"]; delay: Bluebird["delay"]; disposer: Bluebird["disposer"]; @@ -81,7 +111,7 @@ declare global { each: Bluebird["each"]; error: Bluebird["error"]; filter: Bluebird["filter"]; - // finally: Bluebird["finally"]; + // finally: Bluebird["finally"]; // Provided by lib.es2018.promise.d.ts get: Bluebird["get"]; isCancelled: Bluebird["isCancelled"]; isFulfilled: Bluebird["isFulfilled"]; @@ -103,7 +133,7 @@ declare global { suppressUnhandledRejections: Bluebird["suppressUnhandledRejections"]; tap: Bluebird["tap"]; tapCatch: Bluebird["tapCatch"]; - // then: Bluebird["then"]; + // then: Bluebird["then"]; // Provided by lib.es5.d.ts thenReturn: Bluebird["thenReturn"]; thenThrow: Bluebird["thenThrow"]; catchReturn: Bluebird["catchReturn"]; @@ -115,19 +145,18 @@ declare global { value: Bluebird["value"]; /* - * Copy&paste ::then and ::catch from lib.es2015.promise.d.ts, because Bluebird's typings are not + * Copy&paste ::then and ::catch from lib.es5.promise.d.ts, because Bluebird's typings are not * in line with the standard lib. * - * This is only needed for es5 target, which doesn't include the lib.es2015.promise.d.ts typings. + * #std-lib-copy&paste-to-remove * - * @todo Make Bluebird's typings be in line with the standard lib. + * @todo See the comment near the top of the file about code marked with #std-lib-copy&paste-to-remove */ - then(onfulfilled?: ((value: T) => T | PromiseLike) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike) | undefined | null): Promise; - then(onfulfilled: ((value: T) => T | PromiseLike) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike): Promise; - then(onfulfilled: (value: T) => TResult | PromiseLike, onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; - then(onfulfilled: (value: T) => TResult1 | PromiseLike, onrejected: (reason: any) => TResult2 | PromiseLike): Promise; - catch(onrejected?: ((reason: any) => T | PromiseLike) | undefined | null): Promise; - catch(onrejected: (reason: any) => TResult | PromiseLike): Promise; + then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, + onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null + ): Promise; + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; /* * TypeScript disallows adding overrides via `catch: typeof Bluebird.prototype.catch`. Copy&paste them then. @@ -142,7 +171,11 @@ declare global { catch(predicate: Object, onReject: (error: any) => U | PromiseLike): Bluebird; /* - * See comments above `then` for the reason why this is needed. Taken from esnext.promise.d.ts. + * See comments above `then` for the reason why this is needed. Taken from es2018.promise.d.ts. + * + * #std-lib-copy&paste-to-remove + * + * @todo See the comment near the top of the file about code marked with #std-lib-copy&paste-to-remove */ finally(onfinally?: (() => void) | undefined | null): Promise; } @@ -153,7 +186,7 @@ declare global { interface PromiseConstructor { new (callback: (resolve: (thenableOrResult?: T | PromiseLike) => void, reject: (error?: any) => void, onCancel?: (callback: () => void) => void) => void): Promise; - // all: typeof Bluebird.all; + // all: typeof Bluebird.all; // Provided by lib.es2015.d.ts any: typeof Bluebird.any; attempt: typeof Bluebird.attempt; bind: typeof Bluebird.bind; @@ -176,10 +209,10 @@ declare global { promisify: typeof Bluebird.promisify; promisifyAll: typeof Bluebird.promisifyAll; props: typeof Bluebird.props; - // race: typeof Bluebird.race; + // race: typeof Bluebird.race; // Provided by lib.es2015.d.ts reduce: typeof Bluebird.reduce; - // reject: typeof Bluebird.reject; - // resolve: typeof Bluebird.resolve; + // reject: typeof Bluebird.reject; // Provided by lib.es2015.d.ts + // resolve: typeof Bluebird.resolve; // Provided by lib.es2015.d.ts some: typeof Bluebird.some; try: typeof Bluebird.try; using: typeof Bluebird.using; @@ -187,9 +220,9 @@ declare global { /* * Copy&paste from lib.es2015.promise.d.ts, because Bluebird's typings are not in line with the standard lib. * - * This is only needed for es5 target, which doesn't include the lib.es2015.promise.d.ts typings. + * #std-lib-copy&paste-to-remove * - * @todo Make Bluebird's typings be in line with the standard lib. + * @todo See the comment near the top of the file about code marked with #std-lib-copy&paste-to-remove */ all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; @@ -219,6 +252,10 @@ declare global { /* * Declare the `Promise` variable. This is needed for es5 only and is a no-op for all other targets. + * + * #std-lib-copy&paste-to-remove + * + * @todo See the comment near the top of the file about code marked with #std-lib-copy&paste-to-remove */ var Promise: PromiseConstructor; }