12

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

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
Nguyen Hoang Vu
  • 751
  • 2
  • 14
  • 35

1 Answers1

1

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
> so-71099311@0.1.0 start
> npm run compile && node dist/main.js


> so-71099311@0.1.0 compile
> tsc

Hello Nguyen
jsejcksn
  • 27,667
  • 4
  • 38
  • 62
  • 2
    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. – leonheess May 13 '22 at 10:37
  • @leonheess 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. – jsejcksn May 13 '22 at 15:04
  • No? The .js files all lie within `dist`. `Cannot find module './module.js' or its corresponding type declarations.` – leonheess Jun 18 '22 at 22:53
  • @leonheess You might want to reference the [module resolution documentation](https://www.typescriptlang.org/docs/handbook/module-resolution.html) 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 --traceResolution` – jsejcksn Jun 19 '22 at 01:31