Top-level await in TypeScript
The 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" occurs when trying to use await outside of an async function in TypeScript without proper configuration.
Understanding the Problem
Top-level await allows you to use await at the top level of a module without wrapping it in an async function. This feature requires specific TypeScript compiler settings:
modulemust be set toesnextorsystemtargetmust bees2017or higher
Solutions
Method 1: Configure tsconfig.json Properly
Update your tsconfig.json with the correct settings:
{
"compilerOptions": {
"lib": ["es2020"],
"module": "es2022",
"moduleResolution": "node",
"target": "es2022",
"outDir": "dist"
}
}WARNING
When compiling with tsc filename.ts, TypeScript ignores tsconfig.json. Always compile using tsc without filename arguments to use your configuration.
Method 2: Use tsx for TypeScript Execution
tsx is a modern tool that runs TypeScript files directly without complex setup:
- Ensure
"type": "module"in yourpackage.json - Install tsx:
npm install tsx- Run your TypeScript file:
npx tsx file.tsMethod 3: Wrap in Async Function (Legacy Approach)
If you can't modify your TypeScript configuration, wrap your await calls:
const createAccount = async () => {
const account = await stripe.accounts.create({
type: 'express',
});
return account;
};
createAccount().then(account => {
// Handle the account object
});Best Practices
- Modern Approach: Use
tsxfor development and propertsconfig.jsonsettings for production - File Extensions: Use
.mtsextension for ES modules with top-level await - Module Resolution: Set
"moduleResolution": "node"for Node.js environments
TIP
Top-level await is natively supported in modern Node.js versions (v14.8+). Ensure you're using a recent Node.js version for best compatibility.
Common Pitfalls
- Compiling with
tsc filename.tsinstead of justtsc - Missing
"type": "module"inpackage.json - Using outdated Node.js versions that don't support ES modules
By following these solutions, you can successfully use top-level await in your TypeScript projects with proper configuration and tooling.