Skip to content

"module": "node16" should support extension rewriting #49083

Closed
@arendjr

Description

@arendjr

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdOut of ScopeThis idea sits outside of the TypeScript language design constraintsSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions