arendjr · GitHub

Bug Report

TypeScript 4.7 RC introduces the "module": "node16" setting. When used, this requires users to use the .js extension in import paths. I strongly believe this to be a mistake and TypeScript should instead allow users to use the .ts/.tsx extension of the source file. It would then be the TS compiler’s responsibility to rewrite this to the output file as necessary.

I have several reasons for requesting this change:

  • The file with the .js extension most likely does not exist on disk. It may exist on disk if a build has been created and the output is placed right alongside the sources (not a common configuration), but otherwise the file is simply not there or in a different place than one might expect. This is confusing to users, because they need to manually consider how output files are created.
  • Using the .js extension makes the source code less portable for full-stack projects. If a user wants to use the same sources for a frontend project that uses a bundler, they will be out of luck. A bundler would be able to understand a reference to the .ts file (because that one actually exists on disk!), but would struggle with references to files that do not exist for its configuration.
  • Using the .js extension makes the source incompatible with Deno projects, as they use the .ts/.tsx extensions, because those are the ones that actually exist.
  • Using the .js extension is inconsistent with type import. Does import type { MyType } from “./myFile.js” even work? It would not make sense because the JS file contains no types. But if it doesn’t work, does that mean I still have to use the .ts extensions only for the types? That would be highly annoying.

🔎 Search Terms

extension rewriting esm module

🕗 Version & Regression Information

TypeScript 4.7. RC1

  • I was unable to test this on prior versions because the feature is new to version 4.7.

🙁 Actual behavior

I am forced to write import { myFunction, type MyType } from “./myFile.js” despite “./myFile.js” not being a valid path in my project.

🙂 Expected behavior

I should be able to write import { myFunction, type MyType } from “./myFile.ts” because “./myFile.ts” is the actual file I am referring to. Upon compilation I would expect TypeScript to rewrite the path so the output works correctly too.

Read the original on github.com ↗