Search code examples
node.jstypescriptnode-modulestsconfig

Typescript compile issue (error TS2705 - ES2015 --lib option)


When compiling a typescript file with tsc -p . I'm getting the following error

error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.

9 async function fetchImages(param1: string): Promise<string[]> {

Compiling with the lib option tsc --lib es5 doesn't solve it

Could could someone explain a bit more about the --lib option and how this would fix it as it didn't in my case.

node -v
v19.9.0

tsc -v                    
Version 5.1.0-dev.20230512

tsconfig:

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Language and Environment */
    "target": "es5",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

    /* Modules */
    "module": "es6",                                /* Specify what module code is generated. */
    "rootDir": ".",                                  /* Specify the root folder within your source files. */
    "baseUrl": ".",                                  /* Specify the base directory to resolve non-relative module names. */

    /* Emit */
    "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
    "outDir": "dist",                                   /* Specify an output folder for all emitted files. */

    /* Interop Constraints */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
    
    /* Completeness */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

Solution

  • As has already been mentioned, your tsconfig.json settings are not really appropriate for a Node 19 project (and possibly for a Node project in general)...

    However, your issue is a bit more nuanced to be precise. Consider the following:

    {
      "compilerOptions": {
        "rootDir": "src/",
        "listFiles": true,
        "module": "es6",
        "skipLibCheck": true,
        "target": "es5",
      },
    }
    
    async function doWork() : Promise<string[]> {
        return null;
    }
    
    $ tsc
    index.ts:1:27 - error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.
    
    1 async function doWork() : Promise<string[]> {
                                ~~~~~~~~~~~~~~~~~
    

    The exact reason for this is that native Promise support was not introduced until ES6 aka ES2015, not ES5, despite async being available.

    Try removing the return type from the function:

    async function doWork()  {
        return ["a", "b", "c"]
    }
    

    Interestingly, this code will compile. If you look at the transpiled JS, it looks like this:

    function doWork() {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, ["a", "b", "c"]];
            });
        });
    }
    

    The compiler is shimming both the awaiter and generators which are also not available until ES6. Note there is no Promise or Generator type here.

    Changing your target to es6 where native Promise support was added resolves the issue. The transpiled JS looks like this:

    function doWork() {
        return __awaiter(this, void 0, void 0, function* () {
            return ["a", "b", "c"];
        });
    }
    

    You can see the native Generator (function*) being emitted here.

    In summary, you are targeting ES5 which does not have native Promise support, hence the errors using that type. The solution is to either provide a Promise-compatible implementation or use ES6.

    However, if you are really writing a Node 19 application, you should probably use the completely different compiler options regardless.