Top-level await and Import in Typescript
Asked Answered
S

1

14

I'm studying Typescript and running into a problem. I want to use the import and top-level await but currently, I can only use one at a time.

Here is my config in tsconfig.json which allows me to use import

"target": "ESNext",
"module": "ESNext"

And this one allows me to use top-level await:

"module":"commonjs"

I added

"type":"module"

to my package.json

Is there any way that I can take advantage of both features? Many thanks.

I'm using Nodejs 16 and Typescript 4.5.5

Successive answered 13/2, 2022 at 9:17 Comment(0)
N
4

Yes, you can use both. Here's info to help you reproduce a successful test:

Node.js (LTS) version:

$ node --version
v16.14.0

./package.json:

{
  "name": "so-71099311",
  "version": "0.1.0",
  "private": true,
  "description": "",
  "type": "module",
  "scripts": {
    "compile": "tsc",
    "start": "npm run compile && node dist/main.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@types/node": "^17.0.17",
    "typescript": "^4.5.5"
  }
}


./tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "exactOptionalPropertyTypes": true,
    "isolatedModules": true,
    "lib": [
      "esnext"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noUncheckedIndexedAccess": true,
    "outDir": "dist",
    "strict": true,
    "target": "esnext",
    "useUnknownInCatchVariables": true
  },
  "include": [
    "./src/**/*"
  ]
}


./src/module.ts:

export function greet (name = 'world'): void {
  console.log(`Hello ${name}`);
}


./src/main.ts:

import {greet} from './module.js';

const name = await Promise.resolve('Nguyen');
greet(name);


In your console:

$ cd /path/to/the/directory/where/you/created/these/files
$ npm install
$ npm run start
> [email protected] start
> npm run compile && node dist/main.js


> [email protected] compile
> tsc

Hello Nguyen
Nehru answered 13/2, 2022 at 10:24 Comment(4)
That doesn't work. You import './module.js' but it is './module.ts'. And you can't change the import to end on .ts because that's not allowed. You also can't remove the .js entirely because of "type": "module". It's a catch-22.Whiffle
@Whiffle If you copy the files onto your device and run the code, you will see that it does work. TypeScript resolves specifiers ending in .js which are local modules to their respective .ts counterparts as appropriate.Nehru
No? The .js files all lie within dist. Cannot find module './module.js' or its corresponding type declarations.Whiffle
@Whiffle You might want to reference the module resolution documentation to refresh/learn about the way TS resolves specifiers. If you followed the steps exactly, then you shouldn't see that error using Node.js >= 16.14. What's the output of the following command? node --version && cat -b ./package.json ./tsconfig.json ./src/module.ts ./src/main.ts && tsc --traceResolutionNehru

© 2022 - 2024 — McMap. All rights reserved.