Rewrite relative import extensions with flag by andrewbranch · Pull Request #59767 · microsoft/TypeScript (original) (raw)

This PR adds --rewriteRelativeImportExtensions to support transforming module specifiers from e.g. "./utils.ts" to "./utils.js". A module specifier will be statically rewritten or shimmed during JS emit if it meets all of these criteria:

Error checking

Errors are issued in an attempt to catch common mistakes:

Syntax support

Scenario Example input Operation Example output
Import declarations import "./foo.ts" Rewrite import "./foo.js", require("./foo.js")
Export declarations export * from "./foo.ts" Rewrite export * from "./foo.js"
Import equals import foo = require("./foo.ts") Rewrite import foo = require("./foo.js")
Import calls with qualifying literal argument import("./foo.ts") Rewrite import("./foo.js")
Require calls in JS with qualifying literal argument require("./foo.ts") Rewrite require("./foo.js")
Import calls with non-literal argument import(getPath()) Shim import(__rewriteRelativeImportExtension(getPath()))
Require calls in JS with non-literal argument require(getPath()) Shim require(__rewriteRelativeImportExtension(getPath()))
Import calls with non-qualifying literal argument import("foo") None import("foo")
Require calls with non-qualifying literal argument require("foo") None require("foo")
Require calls in TS require("./foo.ts") None require("./foo.ts")
Indirected require calls (require)("./foo.ts") None (require)("./foo.ts")

Limitations and future work

This PR doesn’t change how module resolution works, so it’s still possible to reference a .ts file by a .js module specifier:

// @Filename: a.ts export {};

// @Filename: b.ts import {} from "./a.js"; // Always ok

We discussed that it’s probably desirable to turn this functionality off under --rewriteRelativeImportExtensions (and --allowImportingTsExtensions), since these options are a strong indicator that the user is going to run the input TS files in a TS-native runtime like Bun or node --experimental-strip-types. That would be a breaking change and isn’t included in this PR.

tslib PR: microsoft/tslib#270
Fixes #59597