Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Top-level ‘await’ expressions are only allowed when the ‘module’ option is set to ‘esnext'

I am going through Stripes integration steps and have come across an error for my code found in step 2.1 (https://stripe.com/docs/connect/collect-then-transfer-guide#create-an-account-link)

How do I fix this error?

Code:

const stripe = require('stripe')('someID');
const account = await stripe.accounts.create({
  type: 'express',
});

Error:

Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.ts(1378)

like image 694
Kev Wats Avatar asked Mar 05 '21 04:03

Kev Wats


People also ask

How do you use await top level?

Top level await You can use the await keyword on its own (outside of an async function) within a JavaScript module. This means modules, with child modules that use await , wait for the child module to execute before they themselves run. All while not blocking other child modules from loading.

How do I enable top level await in TypeScript?

To use top-level await in TypeScript, you have to set “target” to es2017 or higher. The “module” option in “tsconfig. json” has to be set to esnext or system . Your code also has to run on Node.

How do you refactor top level await?

To solve the error "Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext'", use the await keyword in an async function or set the module option to es2022 and target to es2017 in your tsconfig. json file.

What is async and await in TypeScript?

Asynchronous functions are prefixed with the async keyword; await suspends the execution until an asynchronous function return promise is fulfilled and unwraps the value from the Promise returned.


2 Answers

You can wrap your code for const account inside an async function as your target option doesn't support top level await.

 const account = async () => {
        await stripe.accounts.create({
          type: "express",
  });
};

It depends on your code whether you want to return something or you want to perform some other tasks after await.

Incase if you want to use top level await, More about using top level await is on https://stackoverflow.com/a/56590390/9423152

This it just a workaround of the problem not the exact solution as referred by other users. Furthermore, You can try changing the module option and target in tsconfig file if you are using Typescript on node.

like image 63
Bibek Avatar answered Oct 23 '22 04:10

Bibek


To fix the error and use top level await:

Here's something you may have missed:

tsc ignores the configuration in tsconfig.json when provided with a file name to compile.

Solution 1 - specify a ts file explicitly and use command line args to provide the right options:

$ npx tsc --help
tsc: The TypeScript Compiler - Version 4.6.2
                                                                                                                     TS
COMMON COMMANDS

  ....

  tsc app.ts util.ts
  Ignoring tsconfig.json, compiles the specified files with default compiler options.

So you'll need to use:

npx tsc -t es2022 -m es2022 --moduleResolution node --outDir dist src/runme.mts

Solution 2 - use tsc specifying the .ts file using src in tsconfig.json

Here's a config with the correct settings for top level await:

{
  // https://www.typescriptlang.org/tsconfig#compilerOptions
  "compilerOptions": {
    "esModuleInterop": true,
    "lib": ["es2020"],
    "module": "es2022",
    "preserveConstEnums": true,
    "moduleResolution": "node",
    "strict": true,
    "sourceMap": true,
    "target": "es2022",
    "types": ["node"],
    "outDir": "dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Make sure the include folders in your tsconfig.json contain your typescript that uses top level await:

npx tsc

dist/runme.mjs is generated and my compiled app runs.

like image 7
mikemaccana Avatar answered Oct 23 '22 03:10

mikemaccana