Skip to content

Using lookahead to detect generic JSX elements? #6395

Closed

Description

Initially from a couple different comments, but elaborated here.

Currently, in order to use a generic JSX element, you must alias both the type and interface to a non-generic specialization.

class Select<T> extends React.Component<SelectProps<T>, any> {}

// Alias
type StringSelect = new () => Select<string>
const StringSelect = <StringSelect> Select

const Form = () => <StringSelect items={['a','b']} />

It would be a lot more convenient and consistent to use something like this:

const Form = () => <Select<string> items={['a', 'b']} />

In order to differentiate the latter, you can use a single token of lookahead in the parser to know if it's a generic JSX element:

  • If the next token is a <, like in < Select <, then consume the rest of the type as a generic type. After consuming that:
    • If the next token is a >, then finish the type as a generic type cast.
    • If the next token is an identifier or a { (for spread attributes, when they get implemented), then parse the rest as a JSX element.
    • Otherwise, parse the rest as a type cast.
  • If the next token is a >, like in < Select >, then finish the type as a simple type cast.
  • If the next token is an identifier or a {, then parse the rest as a JSX element.
  • Otherwise, consume the rest as a type cast.

I don't know of any reason that wouldn't be feasible to do, considering async arrow functions, which are already implemented, require potentially a whole call expression of parsing to differentiate between let f = async (x, y), which is a call expression, and let f = async (x, y) => x, which is an async arrow function. (I feel sorry for whoever ends up implementing that in V8, which doesn't support any backtracking or much lookahead for memory reasons.)

/cc @RyanCavanaugh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Domain: JSX/TSXRelates to the JSX parser and emitterRelates to the JSX parser and emitterEffort: DifficultGood luck.Good luck.FixedA PR has been merged for this issueA PR has been merged for this issueHelp WantedYou can do thisYou can do thisSuggestionAn idea for TypeScriptAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions