Typescript: Enable JSX syntax in .ts files

Created on 16 Aug 2018  ·  21Comments  ·  Source: microsoft/TypeScript

Search Terms

JSX, extension, React

Suggestion

How about adding new compiler option to enable JSX syntax in .ts files?
Currently, JSX syntax is available in only .tsx files, but I want to use same extension, .ts, regardless of whether JSX syntax is used.

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. new expression-level syntax)
Add a Flag Declined Suggestion

Most helpful comment

I'd like to see an option to completely disable the <Type>expr casting in favor of allowing JSX in all .ts files. I've just begun migration from Flow to TS and find it frustrating that .tsx is a hard requirement.


edit: I didn't see the above when posting this. I guess we are stuck for now. 😕 🤷‍♂️

we have architectural constraints that disallow the parsing of a file to depend on compiler options

All 21 comments

Increased compiler complexity and yet another compiler flag for questionable gain. Why not just use .tsx?

There are parsing conflicts with <Type>expr expressions and JSX elements that make it impractical to do this, and we have architectural constraints that disallow the parsing of a file to depend on compiler options.

Could we deprecate the <Type>expr expressions in favor of as? This way, there could be an opt-in compiler flag that turns it off and thus removes any ambiguity with JSX elements.

I'd like to see an option to completely disable the <Type>expr casting in favor of allowing JSX in all .ts files. I've just begun migration from Flow to TS and find it frustrating that .tsx is a hard requirement.


edit: I didn't see the above when posting this. I guess we are stuck for now. 😕 🤷‍♂️

we have architectural constraints that disallow the parsing of a file to depend on compiler options

Since #30503 was closed, but has received a lot of feedback from users, here are the reactions from that issue (140 upvotes, 27 downvotes, 22 hearts):

Screen Shot 2019-03-26 at 16 07 27

...or #30503 could just become the open, canonical issue and this one closed @RyanCavanaugh?

I don't see value in prioritizing drive-by votes via Twitter over organic traffic, nor particularly care to encourage people to log new issues because they didn't like the resolution of prior ones.

Got it, no problem.

I do think that Twitter, the work of developer advocates and other publicity can be an effective tools to highlight issues that developers aren't aware are possible to change (or aren't aware where to go to demonstrate about them). Organic traffic is unfortunately a very bad way of getting real developer feedback:

  • the vast majority of developers do not engage because of either not knowing it's possible, not knowing where to look, or other social pressures
  • even as an experienced open sourcerer I often have trouble finding the issues I'm looking for, even just in one repo (VSCode as an example)

However, I do agree that votes can be biased in this regard. And I also agree that reopening closed issues is untenable.

On this particular issue though, guy feeling says that the vote represents how the community feels about it:

  1. a lot of people use JSX and would like to not have to rename their files, generating sometimes very confusing or ugly version control diffs
  2. another group of vocal people care that JSX is not put into .ts files, either for anti-JSX reasons or because of not wanting to change TS semantics for this
  3. another, probably larger group doesn't care what happens

It's meaningful to distinguish two kinds of votes:

  • I am upvoting because I want/need this feature
  • I am upvoting because someone I respect wants/needs this feature

The latter is often a 10x or 100x multiplier on the former. We've seen this before where Influencers will link an issue on Twitter and suddenly that issue gets dozens of upvotes out of nowhere, and I don't want popular Twitter personalities to be the sole deciders of feature priority.

Reddit has np. links for much the same reason and that's basically how I'd like people coming to our tracker from social media to behave - if you're not personally invested in this, just quiet comprehension is sufficient.

I am personally quite skeptical that all 140 people who upvoted the duplicate issue had just failed to find the issue with the most obvious title possible for this feature back the first time they realized they wanted it.

I am personally quite skeptical that all 140 people who upvoted the duplicate issue had just failed to find the issue with the most obvious title possible for this feature back the first time they realized they wanted it.

It's simple. People are lazy. Most were probably not even looking for it in the first place, but they were willing to give their opinion when the issue was served on a platter. I think you're underestimating how large percentage of the TS community are also using JSX and bothered by the current behavior. The React community is huge.

Since you're not convinced by the votes, I would instead encourage reaching out to known individuals in the TS that use JSX and ask them for feedback. Quality feedback is always better than faceless votes.

I'm going to repost a part of constructive debate from the other topic.

@weswigham pointed out a major obstacle to allowing the syntax as-is in .ts: https://github.com/Microsoft/TypeScript/issues/30503#issuecomment-475417559

My reply was to suggest an alternative:

I wasn't aware of this, great example @weswigham, thank you!
Would it be any less ambiguous if there was a hard requirement on JSX tags in .ts files to be wrapped in braces (like prettier does by default)?

const jsxInDotTs = (<span>
  hello
</span>)

An extra brace is still better than not having JSX in .ts at all :)

Note that I did not research whether this is doable, or if it's still an issue for the parser.

What about JSX in .js files ?

JSX is already allowed in JS files

JSX is already allowed in JS files

Let me clarify, I am using Typescript in .js files (with checkJs,allowJs). yet TypeScript won't recognize JSX in these .js files.

On reason I wish .jsx and .tsx were never "invented" is it's annoying to me that VSCode has separate modes for JS/JSX and TS/TSX. For instance I had someone complain that an extension I wrote doesn't activate in JS, I had recommend to set the default .js language mode to JSX but that wasn't a viable solution for them.

Also, the extra file extensions are just one more piddly detail to configure for tools/package script usage of webpack, eslint, @babel/register, prettier.

Having used JSX in .js files for years with zero problems, a different file extension just feels like a time waster.

I felt the same way when I switched to ts from js. .js files allows JSX, so I created JSX components in my .ts files but nothing was working, after a lot of troubleshooting realised I've to use .tsx to make it work.
now also, a couple of time I create a .ts file and later when I've to use a JSX component in it. I;ve to rename the file extension to .tsx
Not a good dev exp IMHO.

This may or may not be related, but I would like for jsx parsing to be enabled as a default feature (or at least a command line option) so that the ts-node REPL will be able to use JSX for quick experiments in interactive sessions.

How about adding annotation/pragma in ts files to parse jsx @RyanCavanaugh

/** @tsx jsx */
<Comp />

Increased compiler complexity and yet another compiler flag for questionable gain. Why not just use .tsx?

Sometimes we cannot use tsx, because in games tsx is the extension of tiled map files.

Increased compiler complexity and yet another compiler flag for questionable gain. Why not just use .tsx?

As snarky and silly as it may seem, I just don't want to. It's a very subjective thing, but I consider it "dirty" to have two different file extensions for such a slight difference in syntax, merely because the compiler is unable to tell the difference between generics and JSX otherwise.

Sure, I can just use ts and tsx, and whenever the compiler complains about using the wrong syntax for the current file extension, it's pretty easy to just rename it, but all these things add up to a death by a thousand cuts where all the different syntax, flags, all the rules, and all the exceptions to those rules just create more and more stuff that I have to remember, on top of trying to understand what the code is doing, understanding the domain problem I'm trying to solve with code, and a dozen other things.

The same issue exists in JS ecosystem tooling where everything is a plugin, with flags, and config files, but that's a different rant for another day, I suppose... 😖.

As snarky and silly as it may seem, I just don't want to. It's a very subjective thing, but I consider it "dirty" to have two different file extensions for such a slight difference in syntax, merely because the compiler is unable to tell the difference between generics and JSX otherwise.

Sure, I can just use ts and tsx, and whenever the compiler complains about using the wrong syntax for the current file extension, it's pretty easy to just rename it, but all these things add up to a death by a thousand cuts where all the different syntax, flags, all the rules, and all the exceptions to those rules just create more and more stuff that I have to remember, on top of trying to understand what the code is doing, understanding the domain problem I'm trying to solve with code, and a dozen other things.

Well...we already have a '.mjs' extension for ecma modules...but in my experience it actually creates more problems than it solves.

Also, it was my understanding that even the original React creators of the JSX syntax no longer recommend using the .jsx extension, citing issues related to those described in the thread above. If that would have happened sooner, do you think TypeScript would still expect a separate extension?

Also, maybe I'm just imagining this, but didn't we have a separate extension for files that depended on Babel? (Sorry, I don't use that much Babel anymore.)

The bottom line is, unless the syntax is just COMPLETELY different (as in part of a wholly different spec) then the idea using a different file extension doesn't make any sense to me. We're talking about a single syntactical construct here.

Was this page helpful?
0 / 5 - 0 ratings