Type parameters on JSX open tag identifiers cause the JSX block to be highlighted incorrectly
Closed this issue · 11 comments
Edit by @rsese to add code from #34 (comment) and link to Apollo example code
export const TaskListItem = ({ id, children }: taskListItemProps) => (
<Query<taskListItem, taskListItemVariables>
query={TASK_LIST_ITEM}
variables={{ id }}
>
{(queryProps) => {
const { loading, data } = queryProps
if (!loading && data && data.task) {
return (
<Mutations task={data.task}>
{(mutations) => {
return children({ ...queryProps, mutations })
}}
</Mutations>
)
} else {
return children({ ...queryProps, mutations: undefined })
}
}}
</Query>
)
Apollo code example: https://github.com/apollographql/react-apollo/blob/master/examples/typescript/src/Character.tsx
Prerequisites
- Put an X between the brackets on this line if you have done all of the following:
- Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode
- Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/
- Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq
- Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom
- Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages
Description
when adding aliases (?) to a component the rest of the JSX does not render correctly
for example, in the following code
<Query<taskListItem, taskListItemVariables>
query={TASK_LIST_ITEM}
variables={{ id }}
>
{(queryProps) => (
<Mutations id={id}>
{(mutations) => {
const finalProps = { ...queryProps, mutations }
return children(finalProps)
}}
</Mutations>
)}
</Query>
the <taskListItem, taskListItemVariables>
causes the entire jsx block to be rendered incorrectly.
inspecting it looks like the scope goes from:
source.tsx
meta.var.expr.tsx
meta.tag.tsx
entity.name.tag.tsx
support.class.component.tsx
to
source.tsx
meta.var.expr.tsx
variable.other.readwrite.tsx
Versions
Atom: 1.34.0
language-typescript: 0.4.11
Thanks for the report @chrisdrackett 👍 Could you clarify a few things? I haven't played with JSX before so I don't have any context for what you're describing and want to make sure I'm reproducing the right thing:
when adding aliases (?) to a component
What are the aliases in the code snippet?
the rest of the JSX does not render correctly
Can you share a screenshot of what you see and describe what's incorrect?
inspecting it looks like the scope goes from:
Where in the code are you when you're logging the scopes?
Lastly, do things look ok with Tree-sitter disabled?
Here is a screenshot without the typescript alias(? hopefully I'm using the right term, I'm new to ts):
and then after I add the alias:
notice that most the coloring (other than red) is lost after the <Query<taskListItem, taskListItemVariables>
line.
I currently have tree-sitter disabled because the coloring on files with JSX is completely strange when I turn it on. (here is a screenshot of tree-sitter, I believe:)
@chrisdrackett It's easier for someone else to reproduce and debug if you provide text that can be copied. Images are good to see exactly what you're talking about though.
sure, I was asked for screenshots so that is what I provided. Here is the related text:
export const TaskListItem = ({ id, children }: taskListItemProps) => (
<Query<taskListItem, taskListItemVariables>
query={TASK_LIST_ITEM}
variables={{ id }}
>
{(queryProps) => {
const { loading, data } = queryProps
if (!loading && data && data.task) {
return (
<Mutations task={data.task}>
{(mutations) => {
return children({ ...queryProps, mutations })
}}
</Mutations>
)
} else {
return children({ ...queryProps, mutations: undefined })
}
}}
</Query>
)
@Aerijo also, this text was available in my original issue request :D am I missing something? I can provide more if needed!
@chrisdrackett Right, sorry. I only saw the provided images and had a knee jerk reaction.
Adding that extra text makes tree-sitter-typescript interprete the tag as a type assertion, and then it gets an error when it sees the {
of {(queryProps)
. It continues normally, but sees the closing tag as a binary comparison with a regex.
As far as I can tell, that syntax is illegal anyway
Specifically,
The as operator
Recall how to write a type assertion:
var foo = <foo>bar;
This asserts the variable bar to have the type foo. Since TypeScript also uses angle brackets for type assertions, combining it with JSX’s syntax would introduce certain parsing difficulties. As a result, TypeScript disallows angle bracket type assertions in .tsx files.
Does this example compile and run properly?
it does. I got this format from the Apollo Client examples here:
https://github.com/apollographql/react-apollo/blob/master/examples/typescript/src/Character.tsx
not saying those are correct as well, but not only does it compile but I get the correct auto-complete in my editor. I'll keep digging as I'm super new to typescript :)
I stumbled into the same problem today. The syntax is not illegal though, Generic JSX components were introduced in Typescript 2.9. I tried setting the grammar to source.ts, but then I lose emmet, not sure how to proceed.
Confirmed this issue with another maintainer - Tree-sitter doesn't parse this as JSX and is a https://github.com/tree-sitter/tree-sitter-typescript issue.
Updated the issue body with that link to the Apollo example code and the code from #34 (comment).
Hey @as-cii, I'm out of office next week and you have some context on this, so I assigned you. My PRs in tree-sitter/tree-sitter-typescript#68 and #37 should be good to go. I'm just waiting on a second review for the change to tree-sitter-typescript
, and I don't anticipate much change will be needed.