question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Generics with React TSX Language Leave `plain-text` Token Open

See original GitHub issue

Information:

  • Prism version: Test Drive version
  • Plugins: Test Drive plugins
  • Environment: Test Drive page

Description

The generic Foo<string> in the following code breaks syntax highlighting of the second function Add2 with the React TSX language:

function Add1(a, b) { return <div>a + b</div> }

type Bar = Foo<string>;

function Add2(a, b) { return <div>a + b</div> }

Example

Screenshots from Test Drive:

Screen Shot 2020-10-16 at 18 26 59

Screen Shot 2020-10-16 at 18 28 12

https://prismjs.com/test.html#language=tsx

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
RunDevelopmentcommented, Oct 17, 2020

Yes, JSX demands self closing tags to have the slash.

That’s really good. It makes things a lot easier for us.

In my experience of looking at code examples since years across many platforms (also beginner platforms like Stack Overflow), I have rarely if ever seen this pattern. I think it seems like a good trade-off if the user is using TSX - JSX and TypeScript together (…) that they format this very uncommon pattern to this code to this equivalent code for proper highlighting (…).

I can only second that. Formatters like Prettier will automatically insert the line breaks you added, so that we will ever come across the one-liner in the wild is very unlikely indeed. The main reason I’m somewhat against it is that it means that Prism’s highlighting will be very whitespace-sensitive. The whitespace-sensitivity goes both ways: Foo <Bar> should be a simple generic type but it won’t be highlighted as such.

Nevertheless, I’ll make a quick PR for TSX with the lookbehind you proposed. The method isn’t perfect but I think the tradeoffs are worth it. (Let’s keep this issue open even after the PR is merged.)

PS. I also want to point out that inferred type parameters of function expressions (e.g. type Foo = <T>(x: T) => T) will most likely still be highlighted incorrectly even with a CF grammar.

1reaction
RunDevelopmentcommented, Oct 16, 2020

Wonder if this fact could help: there is no matching closing tag for generics but JSX requires a matching closing tag.

Unfortunately, that won’t work for two reasons.

Firstly, there are some tags that are self-closing as per HTML spec without the self-closing syntax (e.g. <br>). I don’t know if JSX/TSX have some restrictions here and actually demand valid XML but I doubt it.

Secondly, nested tags. Let’s look at <div><div></div></div>. Obviously, we can’t stop after the first </div> but that means that we have to count the number of opening and closing divs which is impossible for regexes.

Or, another idea: require a non-letter character [^a-zA-Z] in front of a JSX tag - otherwise assume it’s a generic.

We can actually go a step further here. JSX/TSX sections are compiled down to JS expressions, so know what the character before it has to look like. JS’s regex pattern uses the same idea, so we could just copy the lookbehind.

However, this means that Prism wouldn’t be able highlight beginner-level JSX code like <p>foo <strong>bar</strong></p> which is just sad.


My main idea on how to implement a fix is to not use regexes.

Instead of matching individual HTML tags, we match the whole Markup section. We would wrap each Markup section with its own token and then highlight tags within it. This would make a number of JSX things easier to implement, so I quite like the idea. The problem is that this just can’t be done with regexes - no way. Hence #2595.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Make your react component generic with Typescript - Medium
Using Typescript generics turns out to be a way to make the component cleaner and keep it open for extension, but closed for...
Read more >
VS Code API | Visual Studio Code Extension API
VS Code API. VS Code API is a set of JavaScript APIs that you can invoke in your Visual Studio Code extension. This...
Read more >
How To Use Generics in TypeScript - DigitalOcean
Generics are a fundamental feature of statically-typed languages, allowing developers to pass types as parameters to another type, function, or ...
Read more >
React app with Typescript, Using generic spread expressions ...
You should use typescript eslint parser: // eslintrc.json ... "parser": "@typescript-eslint/parser", ... And also extends typescript babel ...
Read more >
Language Server Protocol Specification - 3.17
The following TypeScript definitions describe the base JSON-RPC protocol: ... version: integer; /** * The content of the opened text document.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found