Skip to content

Allow allowImportingTsExtensions: without either '--noEmit' or '--emitDeclarationOnly' #61213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
5 of 6 tasks
commonpike opened this issue Feb 18, 2025 · 5 comments
Closed
5 of 6 tasks
Labels
Duplicate An existing issue was already created

Comments

@commonpike
Copy link

commonpike commented Feb 18, 2025

πŸ” Search Terms

allowImportingTsExtensions, allow importing ts extensions, emit, noEmit, emitDeclarationOnly, emit declaration only,

βœ… Viability Checklist

Note

Feature would have the user explicitly state they don't want valid JS (eg., as with omitting file extension completely, which is currently a valid syntax for emitting JS, and is more implicit) - Possibly would disagree with goal 4 of the design goals depending on the exact meaning of "clean, idomatic, recognisable". Note this is the same request as #53316

⭐ Suggestion

{
  "compilerOptions": {
    "allowImportingTsExtensions": "iKnowWhatImDoing"
  }
}

Without "moduleResolution": "bundler" and "noEmit": true

TypeScript will now happily emit JavaScript when using this option for allowImportingTsExtensions.

  • true - permits the use of .ts extensions in import/export and requires noEmit or emitDeclarationOnly
  • false - has no effect; disables this option
  • "iKnowWhatImDoing" - permits the use of .ts extensions in import/export

πŸ“ƒ Motivating Example

tsc compiles just fine when the source has imports with .ts extensions and noEmit is false, except

  • it warns about a bad tsconfig, because you apparently removed --noEmit which is required
  • in the compiled output there are still .ts extensions refering to files that are now .js

We can easily fix the compiled output with some postprocessing (like, sed), using tsc for the compilation.
In this workflow, I am using not using a bundler to compile, and I want tsc to emit output. The only problem is the error message thrown by tsc.

πŸ’» Use Cases

  1. What do you want to use this for?
  • use tsc to compile and afterwards manually postprocess the (invalid) output; without using a bundler
  • in particular, properly use .ts extensions in imports in the source code when refering to .ts files
  1. What shortcomings exist with current approaches?
  • tsc reports an error in the config when allowImportingTsExtensions is true but noEmit is false
  • using .js extensions in imports in the source code when refering to .ts files feels invalid
  1. What workarounds are you using in the meantime?

Glad you asked :-)

I've set noEmit: true and moduleResolution: node in tsconfig.json, but from the command line (or package.json), I use

npx tsc && ( npx tsc --noEmit false 1>/dev/null || true ) && postProcessStuff

which effectively runs tsc once without output, if it succeeds runs it with output but surpressing the error and always return true, and then postprocesses the result.

@cmdcolin
Copy link

in my setup i am using rewriteRelativeImportExtensions: true, with allowImportingTsExtensions:true (not sure if that helps?? i was just stumbling on this because the error message "Option 'allowImportingTsExtensions' can only be used when either 'noEmit' or 'emitDeclarationOnly' is set." does not mention rewriteRelativeImportExtensions but it seems to fix it)

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Feb 24, 2025

use tsc to compile and afterwards manually postprocess the (invalid) output; without using a bundler

We consider anything that has its own interpretation of module specifiers to be a bundler, so something that postprocesses the output names qualifies as that. To wit, we don't understand what the limitations of your processing are, and can't make any assumptions about what path transforms do/don't work in your setup.

What's wrong with using bundler mode in this scenario?

@commonpike
Copy link
Author

allowImportingTsExtensions requires both noEmit and "moduleResolution": "bundler". Bundler is fine, you could argue the postprocessing that we do is a form of bundling. But before that, we are using tsc to create the output (using noEmit:false). This generates error messages and then actually works.

Please note rewriteRelativeImportExtensions: true that @cmdcolin mentions above might actually solve my particular use case, I haven't tried it yet. If it does, the error message shown at allowImportingTsExtensions should ideally mention that.

@RyanCavanaugh
Copy link
Member

Correct; see #60397

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 25, 2025
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants