TypeScript
TypeScript copied to clipboard
Design Meeting Notes, 8/20/2024
Reconsidering a flag to rewrite .ts to .js in emit in light of TS support in Node.js
https://github.com/microsoft/TypeScript/issues/59597#issuecomment-2287466184
- Traditionally, we've said we will never rewrite any module specifier.
- What's changed?
--experimental-transform-typesand--experimental-strip-typesare now in Node.js.- Here, you must reference your files with an explicit
.ts-like extension.
- Here, you must reference your files with an explicit
- Today, we have
allowImportingTsExtensionsto allow this, but you must havenoEmitturned on. - People want a mode where they can emit to
.jsbut still reference.tsfiles.- Why?
- Maybe you were using these transform types for development, but need to emit to JS for production.
- Maybe you need to publish to npm (can't load
.tsfromnode_modules).
- Why?
- So we are reconsidering TS never rewriting paths.
- What are the rules for when TypeScript can do this?
- Paths must begin with a
.or... - The path cannot be a declaration file path (i.e. one cannot explicitly reference a
.d.tsfile). - The path must be a
.ts,.tsx,.cts, or.mtsfile.
- Paths must begin with a
.tsx- We will rewrite
.tsxto.jsif--jsxisreact,react-jsx, orreact-jsxdev. - We will rewrite
.tsxto.jsxif--jsxisreact-native.
- We will rewrite
- Error checking.
- We will do a naive transform, but we will need to see if something will improperly be transformed.
- For example,
import foo = require("./foo.ts");will be transformed toimport foo = require("./foo.js");, which is incorrect if the original file wasfoo.ts.ts. - Can we do something about incorrect
importandexportsubpaths?- We don't rewrite subpaths, but people can write
exportsandimportsinpackage.jsonthat resolve to.tsfiles. Won't run on publish. - Mmmmaybe, we haven't settled on anything on this yet.
- We don't rewrite subpaths, but people can write
- Is the request something like "downleveling"?
- Kind of. It's for older runtimes, it's for
node_modules. - Are there other less-obvious features that need to be downleveled?
- Don't want to over-generalize on this problem space.
- Kind of. It's for older runtimes, it's for
- Are there other
- What about
--outDir? Shouldn't we rewrite paths relative tooutDir?- If you rewrite
../../other-project/src/foo.ts, don't you want to rewrite this to../../other-project/dist/foo.js?- Uh.
- If you rewrite
moduleSuffixes?- Can ban this one...probably.
- What about
- Are we fighting the tide with this stuff? Should we just say the runtime should support
.tseverywhere and that's what people use?- Maybe long-term? There are lots of issues with that, but this is nearer-term.
- What do we do with
import type?- Presumably, we would rewrite these to
.jsas well, right? - We can leave them as-is technically.
- We should test that.
- Presumably, we would rewrite these to
- Lots of hypotheticals around using Deno and Bun and then going broader across runtimes.
- Is that realistic? dnt probably does this better than we can.
- Are we going to error if users write
.jsimports instead of.ts? It's going to error and users are not going to know why. - We probably should look at if JSR does the same transforms that we're looking to do.
- This is experimental in Node.js. Should this be experimental as well?
- Supports other tools/use-cases as well.
- Let's talk about dynamic
import(...)calls.- Some of these are statically analyzable, but some are not.
- e.g.
import(someVariable);
- e.g.
- One option is a runtime shim like
__fixExtension. - Another option is to just not rewrite these at all - means you can only have static imports, and users have to write their own shimming logic before calling
import()on totally dynamic contents. - Leaning a little towards just making this work with a helper.
- tslib?
- Yes, but you might want this fixed (file extensions might not be recognized).
- Well users can lock on a tslib.
- tslib?
- Some of these are statically analyzable, but some are not.
- This is in theory simple enough - so simple it could be a standalone tool. Which is an argument both for and against doing it.
- People have written them, but they don't get the error checking.
- Feels like we need answers for
moduleSuffixesoutDir
- If people want to use these modes, they usually don't want to use
tscin the tight loop anyway, right? Why do people want to writetsc? Some other tool can do this rewriting.- Declaration files
- How do you avoid the
../../src/foo.tsvs.../../dist/foo.jsproblem?- Is it a problem? Doesn't work today if you reference the input file.
- But that's the whole story - you're running off of input files. And the way people avoid thinking about this is
imports/exportssubpaths inpackage.json, workspaces, or path mappings.
- But that's the whole story - you're running off of input files. And the way people avoid thinking about this is
- Probably needs custom conditions and non-relative paths.
- Though are there custom conditions that don't get triggered within
node_modules? Because you don't want to resolve to the.tsfiles innode_modules(they'll fail at runtime!).
- Though are there custom conditions that don't get triggered within
- Is it a problem? Doesn't work today if you reference the input file.
- There are a LOT of issues regarding deployment, project structuring, scaling, etc. that need to be solved. Needs to fundamentally be built into how Node.js itself supports TypeScript.
We probably should look at if JSR does the same transforms that we're looking to do.
From https://jsr.io/docs/publishing-packages#jsr-package-rules, it looks like JSR doesn’t support publishing code that references itself with package.json "imports" or self-name imports. I think files within each package have to reference each other with relative imports. @lucacasonato is that right?
Currently yes. We are currently discussing whether it is useful to allow this though.