Sven-Michael Stübe Sven-Michael Stübe - 10 days ago 9
TypeScript Question

Using es6-promise with TypeScript 2.1 ES5 Webpack (async/await)

I try to use

es6-promise
with TypeScript 2.1.1 targeting ES5 and webpack.

app.ts

import "es6-promise/auto";

export class Foo {
bar() : Promise<string>{
return Promise.resolve("baz");
}
}


webpack.common.js

const path = require('path');
var webpack = require('webpack');

module.exports = {
entry: {
'app': './app.ts',
},

output: {
path: 'dist/ie',
filename: '[name].js'
},

resolve: {
extensions: ['', '.ts', '.js']
},

devtool: 'source-map',

module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader']
},
]
},
plugins: [
new webpack.ProvidePlugin({
Promise: 'imports?this=>global!exports?global.Promise!es6-promises'
}),

]
};


package.json

{
"name": "foo",
"ieArtifactName": "foo",
"version": "3.0.0-1",
"description": "...",
"main": "src/app.ts",
"author": {
"name": "...",
"email": "...",
"url": "..."
},
"dependencies": {
"@types/es6-promise": "0.0.32",
"@types/jquery": "^2.0.34",
"@types/underscore": "^1.7.34",
"es6-promise": "^4.0.5",
"es6-promise-promise": "^1.0.0",
"es6-promises": "^1.0.10",
"rxjs": "5.0.0-beta.12",
"zone.js": "^0.6.23"
},
"devDependencies": {
"awesome-typescript-loader": "=2.2.4",
"clean-webpack-plugin": "^0.1.14",
"css-loader": "^0.26.0",
"exports-loader": "^0.6.3",
"http": "0.0.0",
"https": "^1.0.0",
"imports-loader": "^0.6.5",
"load-grunt-tasks": "^3.5.2",
"node-static": "^0.7.9",
"pug": "^2.0.0-beta6",
"pug-html-loader": "^1.0.9",
"raw-loader": "^0.5.1",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"typescript": "^2.1.1",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.14.1",
"webpack-merge": "^0.14.0"
}
}


I start webstorm using the command line

webpack --config config/webpack.common.js


The behavior is the following:


  • Webstorm 2016.3.1 highlights everything fine.

  • compiler runs

  • compiler shows 2 errors


    ERROR in [default] D:...\app.ts:4:16
    Cannot find name 'Promise'.



I tried
es6-promise
,
es6-promises
,
es6-promise-promise
and a bunch of import expressions.

When I add
import {Promise} from "es6-promise"
webstorm highlights it as unused import but the error is gone. Is it possible to use Promises targeting ES5 without import? Because after changing the target to ES6 I'd have to touch every file and remove the import.

Problems with async



My goal is to be able to use async/await, because I'm used to it from C# and I hate the callback hell. If I change the code to

export class Foo {
async bar() : Promise<string>{
return "baz";
}
}


The compiler complains again


Cannot find name 'Promise'.


Adding the import
import {Promise} from "es6-promise";
makes it even worse.


Duplicate identifier 'Promise'. Compiler reserves name 'Promise' in top level scope of a module containing async functions.

Answer

You can make the TypeScript compiler aware of ES2015 promises by adding "es2015.promise" to the list of library files to include in your tsconfig.json:

{
    "compilerOptions": {
        "lib": [
            "dom",
            "es5",
            "scripthost",
            "es2015.promise"
        ]
    }
}

Native promises were only introduced in ES2015 and are not available in ES5, which you're targeting. That's why the TypeScript compiler says it can't find the name Promise. Since you're providing a polyfill, there will be a Promise at runtime. The above solution makes TypeScript aware of that.

Comments