You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Handling input file extensions other than .ts, .js, .tsx, and .jsx #10939
There has been multiple requests/issues for a more flexible use of file extensions. There are a few requests, but to summarize, they fall into one of the following two buckets:
Today the file extensions are used in multiple places:
Discovering files from tsconfig.json
Module resolution
JSX syntax parsing
Use of specific features (e.g. type annotations in .js files)
Error reporting (e.g. no semantic errors for .js files)
The generated output file extension
Proposal:
Add a new compiler option extensions that would be a map from a file extension to a ScriptKind entry. If provided, the extension map would override the mapping of the extension.
Different parts of the compiler will need to ask for ScriptKind and not an extension (many already do, e.g. parsing). For tsconfig.json file discovery, the set of keys in extension map would be combined with the set of known extensions.
allowJs in this model would be an alias for "extensions": { ".js" : "JS" }. defining both properties would be an error.
Declaration files are the only exemption of this rule. A .d.ts file meaning can not be changed, and a declaration file can only have .d.ts extension.
That sounds like a good proposal, however there's one problem I see with scoping of these changes. If we set to treat all .js files as TS (for example), and the project mixes un-typed JS (or if you want to gradually type parts of it), it's going to generate errors.
Perhaps instead of assigning "extensions", we could assign glob patterns?
Example:
{"compilerOptions": {"extensions" : {"**/*.ts": "TS","**/*.es": "JS","src/**/*.js": "TS"// treat all JS files inside src as TS}}}
Reacted by Alexander Savin, Ryan Cavanaugh, Aluan Haddad, Robert Knight, Dario Farzati, Aaron Hamid, Omeid Matten, Yuval Greenfield, Jamon Holmgren, garyxuehong and 4 more
Declining in favor of #11158 -- the complexity of determining the grammar, emit extension, etc, especially in a loose file context, doesn't seem to outweigh the benefits relative to simply renaming the input files.
Reacted by Chris, Tristan Shelton, Cody Swartz, Dan Kirkham, Dongwook, Kang, Yang, ldd, Steve Taylor, duzenko, Joe Pea and 27 more
Reacted by Bazyli Brzóska, AbraaoAlves, Yuval Greenfield, Jon Vuri, Dugan, Tom Yaxley, Tristan Shelton, Cody Swartz, Paul Milla, Jacob Pratt and 9 more
Even saying it won't be implemented until TypeScript 3.0 would be better than closing it. :(
Reacted by AbraaoAlves, Christian Bundy, aikeru, Omeid Matten, Dugan, Chris Gervang, Jeremy Short, Jordan Last, Tristan Shelton, Cody Swartz and 9 more
Bazyli Brzóska (@niieani), I agree with you. I am very disappointed by this. I've been having issues with the first scenario Mohamed Hegazy (@mhegazy) listed since the release of VSCode and I have been looking for this feature ever since.
Reacted by AbraaoAlves, Jeremy Short, Jordan Last and Reda Al Sulais
The rational here is what is the use of extensions if they do not mean what they say. a file with type annotations is not .js, and so is a file with JSX syntax. saying that they are is just an outright lie.
For users who feel that .js is more community-friendly than .ts, we felt that this is doing community members a disservice. if the file is meat to contain typescript syntax, and meant to be processed by the typescript compiler, then why not advertise it. it will takes your community members 5 more seconds to know that the file is not really pure JS, so save them the trouble and call it a .ts.
For users who want to use other extensions than .ts. We are open for changing the output extension, since that might be used by other tools down stream. an example for this is the react native case in #11158. If there are similar cases we would be happy to support them as well.
As for tooling, tsserver does support loading files in different modes already. we can add additional server configuration to mark certain extensions, e.g. es or es6 as JS. but do not think support .js as TS or .ts as JS would be needed in these scenarios.
This really comes down to Occam's razor. the simplest solution for tools and for users is for extensions to really mean what they are meant to mean. changing this only leads to complexity in the tooling and confusion to users.
Reacted by normalser, mavericken, Bond, Trotyl Yu, cooper, Chris Gervang, Jordan Last, Pablo Garcia, ExE Boss, Andreas and 2 more
Not sure #11158 would help in the jspm work-flow scenario? If I load and transpile files in the browser, they are loaded with their original extension (.ts, .tsx). If I want to use JSX in one file out of 100 in a package I will have to name all 100 files .tsx since JSPM has a single default extension per package. I would rather name all files .ts since 99 files does not contain any JSX. Another way to do it would be specify the extension in the imports and not having a default extension but AFAIK tsc does not allow that either.
I was actually referring to input extensions, such as import foo from './bar.ts'. From what I gather that will give a compile error in 2.0.3, and this is a good thing. However, that means that we in SystemJS must use the defaultExtension option. So we have to choose one extension to use. So if we in a package have one typescript file with JSX and 100 without JSX, they all have to have the extension TSX. I think this is rather unfortunate. I would rather have all files with extension TS weather they contain JSX or not. For some more background see for example this issue and this issue.
Reacted by Charlike Mike Reagent, Dan Kirkham, Tyler Nickerson, Yordis Prieto, Bykhovtsev Egor, Alexis Tyler, Joe Jirat Onaree, ldd, David Rodriguez Souto, Keldon Rush and 16 more
I made a comment earlier on this thread (which I deleted) saying how I was using the TypeScript compiler to check Flow code (cause the TypeScript tooling is so much better), and how I wished we could allow the checking of JS code with type annotations.
I have to say my use case is completely useless because Flow syntax is different in some cases anyway.
Also, I'm thinking if TypeScript allowed people to specify any file extension then you'd get all these insane people in the JavaScript community who would input *.js files and be like "yeah I only write standards compliant JS, I only use TS for type checking", but their code is littered with non-standard type annotations (cough Flow users cough).
I think it's fantastic that TypeScript type annotations are only allowed inside *.ts, *.tsx and and *.d.ts files and I think it should always be kept that way. It makes it much better for the community. Everyone knows immediately whether they are looking at a TypeScript file, or a standard JavaScript file. GitHub statistics are correct too (has anyone ever spotted metrics on how many people are using Flow? No... because they use the same *.js extension).
Also people won't try doing node myFile.js and have it blow up due to syntax errors because they had non-standard type annotations (ahem, Flow). Imagine some poor kid trying to learn javascript sees a *.js file with all these type annotations inside and is like what? Why doesn't this run?
I could go on and on about the list of reasons why it would be a terrible idea for TypeScript team to support custom extensions...
Reacted by Charlike Mike Reagent, Andrew Lisowski and ExE Boss
Reacted by Ryan Cavanaugh
Reacted by Robin Howard, Mike Patrick, Dan Strokirk, Jean-Sébastien Tremblay, Lê Hoàng Phương and Rigidity
I don't have strong feelings on this issue, but I do have two cents to register.
I think that eliminating file extension restrictions would open up options for people building their own tooling around tsc. That, in and of itself, may or may not be a good enough reason to consider it seriously. At any rate, consider this webpack example:
This person wanted to create a webpack loader that would generate Typescript interfaces from files with (potentially) arbitrary extensions. These interfaces could then be passed along to the Typescript loader of choice.
This was (arguably) more difficult/confusing than it could have been, due to a combination of the file extension restrictions and a poor error message.
While ts-loader has a convenient work-around for this restriction (as documented in the link above), it's not great being tied to one particular loader (or having to write your own).
Again, just two cents. I've been using TS full time for about a year, and I love it. Keep up the good work!
Reacted by Jean-Sébastien Tremblay, ExE Boss and Duane Johnson
With @babel/preset-typescript now being a thing, this needs to be allowed...
We are using Babel for a rather large application, and we would like to slowly add types and use the new Babel preset. We are not interested in fully "switching" to the TypeScript ecosystem, and we are currently using non-TypeScript features via Babel plugins. It makes absolutely zero sense to rename all of our JS files to .ts just to silence the mountain of "'types' can only be used in a .ts file." messages in VS Code... and we can't move forward without a way of silencing those errors, since every single type annotation will be marked as an error, and the other devs will end up just ignoring everything...
...assuming that there is no valid use-case for something that developers keep asking for is never a good thing...
Reacted by Dan Strokirk, ExE Boss, Paul Myburgh, Charlike Mike Reagent, Chris Domigan, Morris Allison III, Jayden Seric, Gaetan-dc, Raphaël Thériault, Rigidity and 4 more
Reacted by Charlike Mike Reagent, Rigidity, S Kuijers and Kositsky Alexandr
Despite a few short comings, I have decided to stay with flowtype for the prime reason that it allows incremental use unlike TypeScript which has been hardheaded on this issue. I suggest you consider it for your project too, Lance Miller (@lellimecnar).
Ryan Cavanaugh (@RyanCavanaugh) can this issue please be re-opened, since there has been a lot of really thoughtful comments since the close date regarding the utility of this (simple) functionality?
Or would it be better to open a new issue?
Reacted by Charlike Mike Reagent, ExE Boss, Cory Gottschalk, Artem Tyurin, fregante, Chadwick Maycumber, wpq0dev, Edmund, Vítor Camacho, Chief Sloperator and 27 more
Reacted by Charlike Mike Reagent, Cory Gottschalk, Rigidity, S Kuijers and Kositsky Alexandr
Reacted by Zacharias Knudsen, Paul Gordon, Vítor Camacho, Rigidity, Kositsky Alexandr and Peter Bridgman
My scenario is to be able to port a large Adobe Animate application from javascript to typescript. Animate uses a naming convention that I probably can't change. Logic for components is stored in files called MyComponent.js and MyComponent.jsfl, where the js file is generated code containing resources and the jsfl file is the code that you write to control the component.
I DO actually want the source file to be Typescript, but I can't use a ts extension because each component has TWO source files and also two different output file extensions.
I have a situation where I want to import modules from a cache, in which all files have had their extensions removed. But I can't import them because of this limitation.
Reacted by Duane Johnson, marekbuxobucek and LankyMoose
Activity
niieani commentedon Sep 15, 2016
That sounds like a good proposal, however there's one problem I see with scoping of these changes. If we set to treat all
.jsfiles as TS (for example), and the project mixes un-typed JS (or if you want to gradually type parts of it), it's going to generate errors.Perhaps instead of assigning "extensions", we could assign glob patterns?
Example:
RyanCavanaugh commentedon Sep 16, 2016
That's a really good idea -- it would solve the "Treat .js as JSX" problem for React Native at the same time
RyanCavanaugh commentedon Sep 28, 2016
Declining in favor of #11158 -- the complexity of determining the grammar, emit extension, etc, especially in a loose file context, doesn't seem to outweigh the benefits relative to simply renaming the input files.
niieani commentedon Sep 28, 2016
Ryan Cavanaugh (@RyanCavanaugh) really?
This solves so much more use cases than just allowing
.jsx. I'm really disappointed. 😞See all the relevant related issues, such as #9839, #9551, #7926, #7699 and #9670, listed by Mohamed Hegazy (@mhegazy).
Even saying it won't be implemented until TypeScript 3.0 would be better than closing it. :(
jbutz commentedon Sep 28, 2016
Bazyli Brzóska (@niieani), I agree with you. I am very disappointed by this. I've been having issues with the first scenario Mohamed Hegazy (@mhegazy) listed since the release of VSCode and I have been looking for this feature ever since.
mhegazy commentedon Sep 29, 2016
The rational here is what is the use of extensions if they do not mean what they say. a file with type annotations is not
.js, and so is a file with JSX syntax. saying that they are is just an outright lie.For users who feel that
.jsis more community-friendly than.ts, we felt that this is doing community members a disservice. if the file is meat to contain typescript syntax, and meant to be processed by the typescript compiler, then why not advertise it. it will takes your community members 5 more seconds to know that the file is not really pure JS, so save them the trouble and call it a .ts.For users who want to use other extensions than
.ts. We are open for changing the output extension, since that might be used by other tools down stream. an example for this is the react native case in #11158. If there are similar cases we would be happy to support them as well.As for tooling, tsserver does support loading files in different modes already. we can add additional server configuration to mark certain extensions, e.g.
esores6as JS. but do not think support.jsas TS or.tsas JS would be needed in these scenarios.This really comes down to Occam's razor. the simplest solution for tools and for users is for extensions to really mean what they are meant to mean. changing this only leads to complexity in the tooling and confusion to users.
jonaskello commentedon Sep 29, 2016
Not sure #11158 would help in the jspm work-flow scenario? If I load and transpile files in the browser, they are loaded with their original extension (.ts, .tsx). If I want to use JSX in one file out of 100 in a package I will have to name all 100 files .tsx since JSPM has a single default extension per package. I would rather name all files .ts since 99 files does not contain any JSX. Another way to do it would be specify the extension in the imports and not having a default extension but AFAIK tsc does not allow that either.
mhegazy commentedon Sep 29, 2016
Output file extension should be allowed in imports. See #4595
jonaskello commentedon Oct 9, 2016
I was actually referring to input extensions, such as
import foo from './bar.ts'. From what I gather that will give a compile error in 2.0.3, and this is a good thing. However, that means that we in SystemJS must use thedefaultExtensionoption. So we have to choose one extension to use. So if we in a package have one typescript file with JSX and 100 without JSX, they all have to have the extension TSX. I think this is rather unfortunate. I would rather have all files with extension TS weather they contain JSX or not. For some more background see for example this issue and this issue.24 remaining items
ctsstc commentedon Jun 18, 2018
2018 and still we're nowhere with this :( 😞
tunnckoCore commentedon Jul 30, 2018
Yea.. And even with 3.0 ...
massimonewsuk commentedon Jul 31, 2018
I made a comment earlier on this thread (which I deleted) saying how I was using the TypeScript compiler to check Flow code (cause the TypeScript tooling is so much better), and how I wished we could allow the checking of JS code with type annotations.
I have to say my use case is completely useless because Flow syntax is different in some cases anyway.
Also, I'm thinking if TypeScript allowed people to specify any file extension then you'd get all these insane people in the JavaScript community who would input *.js files and be like "yeah I only write standards compliant JS, I only use TS for type checking", but their code is littered with non-standard type annotations (cough Flow users cough).
I think it's fantastic that TypeScript type annotations are only allowed inside *.ts, *.tsx and and *.d.ts files and I think it should always be kept that way. It makes it much better for the community. Everyone knows immediately whether they are looking at a TypeScript file, or a standard JavaScript file. GitHub statistics are correct too (has anyone ever spotted metrics on how many people are using Flow? No... because they use the same *.js extension).
Also people won't try doing node myFile.js and have it blow up due to syntax errors because they had non-standard type annotations (ahem, Flow). Imagine some poor kid trying to learn javascript sees a *.js file with all these type annotations inside and is like what? Why doesn't this run?
I could go on and on about the list of reasons why it would be a terrible idea for TypeScript team to support custom extensions...
mikepatrick commentedon Aug 1, 2018
I don't have strong feelings on this issue, but I do have two cents to register.
I think that eliminating file extension restrictions would open up options for people building their own tooling around
tsc. That, in and of itself, may or may not be a good enough reason to consider it seriously. At any rate, consider this webpack example:This person wanted to create a webpack loader that would generate Typescript interfaces from files with (potentially) arbitrary extensions. These interfaces could then be passed along to the Typescript loader of choice.
This was (arguably) more difficult/confusing than it could have been, due to a combination of the file extension restrictions and a poor error message.
While
ts-loaderhas a convenient work-around for this restriction (as documented in the link above), it's not great being tied to one particular loader (or having to write your own).Again, just two cents. I've been using TS full time for about a year, and I love it. Keep up the good work!
duzenko commentedon May 10, 2019
Sorry if I'm duplicating someone else but not being able to move forward with simple things like this is rather frustrating
lellimecnar commentedon Jun 3, 2019
With
@babel/preset-typescriptnow being a thing, this needs to be allowed...We are using Babel for a rather large application, and we would like to slowly add types and use the new Babel preset. We are not interested in fully "switching" to the TypeScript ecosystem, and we are currently using non-TypeScript features via Babel plugins. It makes absolutely zero sense to rename all of our JS files to
.tsjust to silence the mountain of"'types' can only be used in a .ts file."messages in VS Code... and we can't move forward without a way of silencing those errors, since every single type annotation will be marked as an error, and the other devs will end up just ignoring everything......assuming that there is no valid use-case for something that developers keep asking for is never a good thing...
gugadev commentedon Jun 27, 2019
Really, there is no logic reason to do not implement this proposal. This is a must for god's sake.
omeid commentedon Jun 28, 2019
Despite a few short comings, I have decided to stay with
flowtypefor the prime reason that it allows incremental use unlike TypeScript which has been hardheaded on this issue. I suggest you consider it for your project too, Lance Miller (@lellimecnar).JounQin commentedon Jul 24, 2019
Any hack way??? Something like
appendTsPrefixTo?bgraceful commentedon Aug 1, 2019
noun:I verb:am verb:guessing adjective:that noun:there auxiliary verb:is adjective:no noun:way preposition:to verb:run noun:typescript preposition:on indefinite article:a noun:String?
strokirk commentedon Aug 21, 2019
Ryan Cavanaugh (@RyanCavanaugh) can this issue please be re-opened, since there has been a lot of really thoughtful comments since the close date regarding the utility of this (simple) functionality?
Or would it be better to open a new issue?
jfrank14 commentedon Oct 20, 2020
My scenario is to be able to port a large Adobe Animate application from javascript to typescript. Animate uses a naming convention that I probably can't change. Logic for components is stored in files called MyComponent.js and MyComponent.jsfl, where the js file is generated code containing resources and the jsfl file is the code that you write to control the component.
I DO actually want the source file to be Typescript, but I can't use a ts extension because each component has TWO source files and also two different output file extensions.
Rigidity commentedon Feb 6, 2021
josh-sachs-epic commentedon Oct 11, 2021
I came across this proposal while trying to setup nextjs (react) to import css modules without requiring the '.css' extension.
This currently works at runtime, but tsc reports it as an error
ts(2307)tsconfig.json
When I import the module at
src/styles/home.module.cssas such:import styles from @styles/home.moduleit works at compile/runtime, but tsc validation in vscode keeps it flagged as an error.
Doing something like:
import styles from @styles/home.module.cssvalidates fine (as long as I remove.cssfrom the path delaration)Seems to me like using
pathsto extend typescript's base list of source file extensions should be a no brainer... and is 95% working today.RobertAKARobin commentedon Dec 12, 2022
I have a situation where I want to import modules from a cache, in which all files have had their extensions removed. But I can't import them because of this limitation.