TypeScript import rewriting leaves runtime paths to you
TypeScript 5.7 can rewrite relative file extensions for emitted JavaScript. Aliases and computed imports still need a deliberate runtime resolution design.
A TypeScript program that runs directly from source and a JavaScript package built from that source need compatible import paths. TypeScript 5.7 addressed one specific mismatch by rewriting relative TypeScript file extensions during emission. That can simplify a dual source-and-build workflow. It does not make every path understood by the compiler resolvable by the runtime, so a successful type check remains insufficient evidence that the distributed package will start.
Looking back from November 2026, the historical milestone is Microsoft's 22 November 2024 final announcement. The beta announcement was published on 9 October. The design was therefore visible before the assignment week; November marks the final release, not the first public discussion of the option.
Rewriting has a deliberately narrow target
Microsoft described rewriteRelativeImportExtensions for relative paths starting with ./ or ../ and ending in TypeScript extensions, with declaration files excluded. The option rewrites eligible paths to the corresponding JavaScript extension. A reference to ./helper.ts, for example, can become ./helper.js in emitted JavaScript. It leaves already-JavaScript and extensionless paths alone.
The final notes explicitly exclude paths depending on baseUrl or paths, and explain complications around dynamically computed imports. They also distinguish package imports and exports resolution from this local rewriting. The beta supplies earlier design context rather than proof of separate November availability for each surrounding runtime feature.
This article concerns that path boundary, rather than the suspicious-condition diagnostics discussed with TypeScript 5.6. A compiler can reject a mistaken expression and still leave the application with a deployment path that nobody has exercised. Correctness at those two boundaries requires different evidence.
A source import is a promise to a particular loader
Consider an illustrative library whose developers run TypeScript files directly during local work and distribute generated JavaScript to consumers. A source file importing ./helper.ts makes sense to the source-running tool. The generated application needs a path pointing to a generated file. Rewriting that relative extension bridges a clear, local relationship between the two file trees.
The business value is less disagreement between the convenient development path and the delivery artifact. The scope remains local: the team must preserve the expected output structure and ship the referenced file. Rewriting the text of an import cannot rescue a package that omits its helper from distribution.
A consumer also brings a runtime environment. The release notes discuss tools and experimental Node capabilities as they stood in 2024. Their existence then does not imply that every deployed Node version, module mode or browser could execute arbitrary TypeScript source. Record the runtime you actually support rather than borrowing a broader promise from today's tooling.
This is an architectural example, not a package built or executed for this article. Its purpose is to identify the two paths that a real project's verification must cover: source execution and consumption of the emitted artifact.
Aliases need an owner after compilation
An alias can make imports easier to read inside a large repository. If the compiler uses an alias to locate a file, that is evidence about compilation. The runtime still needs to understand the path it receives. An import beginning with an application-specific alias does not become relative merely because it eventually refers to a nearby file.
For a proposed service using such aliases, choose who resolves them in delivery. A bundler might own the transformation, or the runtime might use an explicitly supported package mapping. The right choice depends on the product's deployment model. The mistake is leaving the responsibility unassigned because the editor successfully navigates to the source.
This gets more consequential across packages. A development setup can accidentally depend on source files outside the published package. The local application works because the entire repository is present. A consumer receives a smaller artifact and discovers the missing relationship. Package boundaries need inspection alongside import spelling.
Microsoft's final notes discuss conditional exports as a possible approach for workspace layouts. That is a configuration design requiring care, not a universal instruction to enable a generic development condition everywhere. Keep consumer conditions and source-development conditions explicit so they do not accidentally select unavailable source files.
Computed paths deserve an explicit review
A dynamic import with a path determined by program logic cannot be treated as a simple static filename substitution. The final announcement illustrates this limitation with a function that chooses a path. A migration should inspect these sites rather than assuming that the new option rewrites every string that might later reach import().
For a proposed plugin loader, write down where plugin names originate and how they map to delivered modules. Prefer an explicit set of permitted module references when that fits the product. That recommendation concerns maintainable resolution; it is not a claim that rewriting itself supplies a security policy for untrusted plugin names.
The practical verification is to consume the built artifact under its intended runtime, apart from source-only conveniences. Check a normal entry point and a relevant dynamically loaded path. These are suggested project checks, not experiments performed here. Keep failures distinguishable from type errors so someone can locate the unresolved boundary quickly.
A bundler-managed application may need no change
The strongest counterargument is that an existing build system already owns resolution and produces the correct deployment artifact. Enabling another option may add complexity without improving the product. There is no obligation to adopt the feature solely because the final release includes it.
Use the option when eligible relative imports are the specific obstacle between source execution and JavaScript distribution. Preserve the build system that already solves a broader problem unless a measured maintenance need justifies changing it. During custom software development, ask for a short account of who resolves imports at each stage and evidence that the shipped artifact runs. That account is more valuable than a configuration file that merely looks consistent in the editor.
Paul