How to use Bluebird with current TypeScript?

2019-04-10 10:49发布

问题:

I just don't get it. Once this was relatively easy, I downloaded the snippet from DefinitelyTyped, it assumed it was globally declared, I added the script and it worked. Now it seems that I have no other option that to use a complex package manager and asynchronous loading system, possibly with an optimizer for production.

Ideally I just want some TypeScript code like this

// maybe some import?
Promise.resolve("foo").then(function(msg) { 
    console.log(msg);
}

compile to some JavaScript like this:

Promise.resolve("foo").then(function(msg) { 
    console.log(msg);
}

I want it to be able to run in a browser or in a minimal environment like Rhino. If needed, I can include require.js, almond.js, build with browserify or whatever, but I want it to work without needing XHR.

So far I've tried:

  • Using global (ambient) modules: could not find one for Bluebird anymore.
  • Using ES6 imports with AMD modules, setting outFile to get a bundle of my code and then including files in this order: almond.js, bluebird.js, my-code.js and some code that requires the main module so anything runs: Error: See almond README: incorrect module build, no module name (apparently the bluebird.js I downloaded from the official page does not define a name in AMD, should I build it myself or what...?)
  • The same as in the previous point using full require.js: missing bluebird.
  • The same as in the previous point with a shim like this: requirejs.config({shim: { bluebird: { exports: "Promise" }}}): exception from uncaught JavaScript throw: Error: Mismatched anonymous define() module and the entire code of Bluebird in the error message.
  • Patching the Bluebird definition file: Not allowed in ES6 mode: Subsequent variable declarations must have the same type.

I feel like I've wasted too much time for such an apparently simple request, so I'll try asking StackOverflow :)

回答1:

Instead of using the global declaration files from DT, it's now considered best practice to use typings instead, importing module declaration files.

Eg. for bluebird, you can just typings install bluebird. This code compiles fine for me:

import Promise = require('bluebird')
Promise.resolve("foo").then(function (msg) {
  console.log(msg)
})


回答2:

If, like me, you think using Promise.resolve() to cast/coerce a Bluebird promise seems like it both defeats the stated purpose of Bluebird (“Zero overhead abstraction”, “Runs everywhere”, “Spec compatible”, ...) and brings TypeScript to a cumbersome tipping point, consider using @types/bluebird-global as follows:

npm install --save-dev @types/bluebird-global

Import this once in your main entrypoint.

// The same Promise API, everywhere.
import * as Promise from 'bluebird'
global.Promise = Promise

See DefinitelyTyped issue #11027 for further context.