Alternative to rewriteRelativeImportExtensions & allowImportingTsExtensions #61050
Open
6 tasks done
Labels
Awaiting More Feedback
This means we'd like to hear from more people who would be helped by this feature
Suggestion
An idea for TypeScript
π Search Terms
"rewriteRelativeImportExtensions", "allowImportingTsExtensions", "extension', "rewrite", "tsc"
β Viability Checklist
β Suggestion
Although the recent
rewriteRelativeImportExtensions
tsc option is a big step forward with the more and more needed feature of rewriting.ts
extensions to.js
when compiling with tsc, it suffers of some drawbacks (may emit shims, false-positives, developer de-responsabilisation, ...) and limitations imposed by the very reasonable Typescript design goals or other things well described by Ryan Cavanaugh in #49083 (comment).The older option
allowImportingTsExtensions
is, for its part, a workaround to permit run-in-place usages (directly executing TS sources, with no compilation, as if it was a JS file), that didn't exist at the TS creation time.Today, I want to propose a solution way more generic I never seen before in any conversations around these features/needs. What is complex and incertain for the compiler here? Something very trivial for a human: determining which string literals (please note: "string literals") in the TS source code are paths pointing to TS files that, once built, will point to JS files. Really transforming such strings is not a big deal, but determining which ones is, because it may depends on a huge amount of configurations, alias, module resolver and other wild things. So, if it's so simple for a human, why not asking him/her to bring this knowledge to the compiler?
So, here is the
// @ts-rewrite-ts-extension
comment (the name doesn't matter at this point, and my English is definitely improvable). The main and unique goal of it, is indicating to tsc that it should transform the nearby literal string ending with.ts
to.js
before doing any treatments on this string (also for other members of this family:.tsx
,.mts
, or.cts
to their "j" counterpart). Why I keep talking about string literals and not about paths? Because it absolutely doesn't matter and will permit the developer to handle its own cases, even dynamic imports, explicitly and with no runtime shim.An indirect consequence is, if this transformation occurs before the
allowImportingTsExtensions: false
check (TS5097) in the tsc process, this option doesn't need to be turned on anymore to allow importing.ts
extensions, as they will be seen as.js
(and valid) by this check. It's totally in the spirit of the TS5097 error to forbid clearly invalid paths and to allow those possibly valid once built.This idea is now yours, improve and refine it or maybe even throw it away. π
π Motivating Example
ESM
import
(orexport from
):CJS
require
:ESM functional
import()
:Why not a block form in which all string literals will be transformed?
No matter the reason why the developer wants to rewrite the extension, any eligible literal can be transformed:
π» Use Cases
What do you want to use this for?
Creating TS projects that can run-in-place in Node, but also buildable with tsc and distributed as npm packets, with a unique code base.
What shortcomings exist with current approaches?
See the suggestion block
What workarounds are you using in the meantime?
tsx because it doesn't impose the Node Typescript restriction on extensions, and more recently tried
rewriteRelativeImportExtensions
.Other improvements around this proposition:
.ts
extension, an error may be emitted by tsc, because it's a clear mistake. Bad usage example:The text was updated successfully, but these errors were encountered: