ยท new features

Top-level await in TypeScript 3.8

TypeScript 3.8 introduces a new feature called top-level await. It allows developers to use the `await` keyword without a surrounding `async` function at the top level of a module.

TypeScript 3.8 introduces a new functionality which is called top-level await. It allows developers to use the await keyword without a surrounding async function at the top level of a module.

Contents

Tutorial

Top-level await was originally planned to land in TypeScript 3.7 but was moved to the iteration plan of TypeScript 3.8. The feature itself is the result of the corresponding ECMAScript proposal called "Top-Level Await".

The following video shows how to use top-level await in combination with Node.js v13:

Code

package.json
{
  "dependencies": {
    "axios": "0.19.2"
  },
  "devDependencies": {
    "@types/node": "13.9.0",
    "typescript": "3.8.3"
  },
  "scripts": {
    "client": "node --harmony-top-level-await ./dist/client.js",
    "server": "node ./dist/server.js"
  },
  "type": "module"
}
tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "node",
    "outDir": "dist",
    "rootDir": "src",
    "target": "es2017"
  },
  "exclude": ["dist", "node_modules"]
}
src/client.ts
import axios from 'axios';
 
try {
  const response = await axios.post('http://localhost:8080/', { number: 1 });
  console.log(response.data);
} catch (error) {
  console.error(error.message);
}
src/server.ts
import { createServer } from 'http';
 
const server = createServer();
const port = 8080;
 
server.on('request', (request, response) => {
  const data = [];
  request
    .on('data', (chunk) => data.push(chunk))
    .on('end', () => {
      const body = Buffer.concat(data).toString();
      const payload = JSON.parse(body);
 
      if (typeof payload.number === 'number') {
        response.writeHead(200, { 'Content-Type': 'application/json' });
        response.write(
          JSON.stringify({
            status: 'OK',
          })
        );
        response.end();
      } else {
        response.statusCode = 500;
        response.end();
      }
    });
});
 
server.listen(port, () => console.info(`Server listening on port "${port}".`));

Fallback

There is this handy snippet of a main function if you cannot use top-level await for any reason:

async function main(): Promise<void> {
  // await ...
}
 
main().catch(console.error);

TL;DR

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.js v14.8.0 or later.

Resources

Back to Blog