highlight.js
highlight.js copied to clipboard
(TypeScript) Generic is not picked up properly
Describe the issue
Which language seems to have the issue?
typescript, no auto-detection
Are you using highlight or highlightAuto?
I don't know what this means.
Sample Code to Reproduce
I tried to reproduce the issue using your jsfiddle, but the typescript generic is not even displaying there ¯\(ツ)/¯.
~~https://jsfiddle.net/x3nzp2rf/~~
updated: https://jsfiddle.net/sm706vyd/2/
I have this code on StackOverflow.
meta: https://meta.stackoverflow.com/questions/420116/typescript-syntax-highlight-with-generic-not-picked-up-properly
first observed issue here: https://stackoverflow.com/questions/72794594/typescript-interface-merging-to-make-an-external-libs-interface-property-more-s/73527814#73527814
```lang-ts
import { useWeb3React as useWeb3React_ } from '@web3-react/core'
export const useWeb3React: <T = any>(key?: string) => Modify<
ReturnType<typeof useWeb3React_<T>>,
{ chainId: SupportedChainIds }
> = useWeb3React_ as any
declare global {
type SupportedChainIds = 1 | 4
}
```
Which produces incorrect syntax highlight
import { useWeb3React as useWeb3React_ } from '@web3-react/core'
export const useWeb3React: <T = any>(key?: string) => Modify<
ReturnType<typeof useWeb3React_<T>>,
{ chainId: SupportedChainIds }
> = useWeb3React_ as any
declare global {
type SupportedChainIds = 1 | 4
}
After a tweak I achieve correct syntax highlight
import { useWeb3React as useWeb3React_ } from '@web3-react/core'
export const useWeb3React: < T = any >(key?: string) => Modify<
ReturnType<typeof useWeb3React_<T>>,
{ chainId: SupportedChainIds }
> = useWeb3React_ as any
declare global {
type SupportedChainIds = 1 | 4
}
This is the tweak:
- export const useWeb3React: <T = any>(key?: string) => Modify<
+ export const useWeb3React: < T = any >(key?: string) => Modify<
Expected behavior
(without the spaces around < T = any > - correct is: <T = any>)

Actual behavior

Additional context
I tried to reproduce the issue using your jsfiddle, but the typescript generic is not even displaying there ¯(ツ)/¯.
Because you haven't properly escaped < and > in your HTML, etc.
Not sure I follow this <T = syntax, could a simpler example be given? I believe the problem is this is detected as HTML starting and the end of the HTML can't ever be found, so the highlighting is broken. JSX and types are very hard to parse without a real parser.
#3604 might be a reasonable fix. Thoughts?
I updated the jsfiddle where the exact mentioned issue above can be observed. https://jsfiddle.net/sm706vyd/2/
It can be further reduced to just this, but I find the remaining type definition helpful to showcase the issue.
// Incorrect
export const useWeb3React: <T = any>(key?: string) => any
// Correct
export const useWeb3React: < T = any >(key?: string) => any
A workaround people usually use, which is accepted by the TS community is adding a comma , at the end of the generic, which is allowed in generics lists, but not allowed in JSX and HTML.
type MyFunction = <T = any>(arg: T) = ({ value: T }) // <- would cause highlighting issues
type MyOtherType = <T, U, V>(arg: T) = ({ a: T, b: U, c: V }) // <- example of correct way to use commas in type generics
type MyFunction = <T = any,>(arg: T) = ({ value: T }) // <- Accepted workaround
type MyOtherType = <T, U, V>(arg: T) = ({ a: T, b: U, c: V }) // <- no workaround needed as it already contains commas
I tried adding the comma there, but it didn't change anything. This would have been preferred over adding spaces.
export const useWeb3React: <T = any,>(key?: string) => any
Did you glance at the PR? See the description for the strategy we're using.
Yes, you could add check for this too ,> or , > e.g. <T,> or <T = any,> or <T extends string,> or <T extends string = 'xyz',>, which is a generally accepted escape hatch in JSX-TS world to make parsers realise this is not JSX but TS.
As you see from the other issue it seems like if we add the = case that I think now we're covering all the bases?
Yeah, I guess so.