microsoft / microsoft/TypeScript

Type JSX elements based on createElement function

Ouverte
#14,729 45 commentaires 219 réactions 1 personne assignée Voir sur GitHub

@weswigham y travaille déjà.

Depuis le 5/5/2018.

In Discussion Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

TypeScript currently uses a JSX namespace to type the props of JSX elements. This is customisable by modifying JSX.IntrinsicElements, JSX.ElementClass. However, the type of an element is always JSX.Element.

Of course more interfaces could be added to the JSX namespace. However, I think that with less effort, the compiler could be made more flexible. I'd propose to check JSX elements based on a (virtual) call to JSX.createElement. For instance, the current behaviour can approximately be written like this:

namespace JSX {
  // intrinsic elements
  function createElement<K extends keyof JSX.IntrinsicElements>(tag: K, props: JSX.IntrinsicElements[K], children: JSX.Element[]): JSX.Element;
  // class and functional components
  function createElement<P>(component: (JSX.ElementClass & { new(): { props: P } }) | ((props: P) => JSX.Element), props: P, children: JSX.Element[]): JSX.Element;
}

Given that function signatures are well customisable with the use of generics for instance, most requests can be implemented this way. For instance, #13890 and #13618 would benefit from this change. Libraries that use JSX, but not on the React-way, will benefit from this too.

Proposed semantics

For a JSX element, a virtual call to JSX.createElement is constructed. It is passed three arguments:

  1. Tag name (string) in case of an intrinsic argument (<div />). Otherwise, the identifier is passed (Foo for <Foo />).
  2. An object containing the props.
  3. An array containing the children.

This should be roughly the same as the JSX transform used in the emitter phase. One notable difference is the following: in case of no properties or no children, an empty object or an empty array should be passed, instead ignoring the argument. This makes it easier to write JSX.createElement for library authors.

Backwards compatibility

For backwards compatibility, one of the following approaches could be taken:

  • Use old logic if JSX.createElement does not exist.
  • If JSX.createElement does not exist, default it to (roughly) the definition above.

Error reporting

When type checking the generated function call, the checker can give error messages like "Argument of type .. " or "Supplied parameters do not match any signature of call target". These messages should be replaced when checking JSX elements.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.