Language-tools: Discussion : Comment peut-on taper les événements supportés par un composant

Créé le 5 août 2020  ·  5Commentaires  ·  Source: sveltejs/language-tools

L'objectif est de détecter facilement les fautes de frappe et d'aider à la découverte de tous les événements possibles envoyés par un composant. Après tout, il n'y a aucune raison pour que les entrées (accessoires) puissent avoir un contrat fort mais pas les sorties (événements). En fait, c'est encore plus important que pour les accessoires, car la répartition peut se produire n'importe où dans le fichier, alors que les accessoires sont généralement soigneusement regroupés en haut.

En ce moment, je peux très bien taper on:qoidfoqidjoiqsjd .

Flex, dont le compilateur a également utilisé des annotations personnalisées pour cela : https://github.com/apache/flex-sdk/blob/master/frameworks/projects/mx/src/mx/core/Container.as#L97

Peut-être pourrions-nous organiser une convention spéciale et réservée comme export type Events = {name: 'eventA', data: number} | ...
Avoir le TSDoc reporté sur l'info-bulle côté consommateur serait la cerise sur le gâteau.

enhancement

Commentaire le plus utile

Vous pouvez désormais profiter de la saisie createEventDispatcher introduite dans Svelte 3.25.0. Si tu fais

const dispatch = createEventDispatcher<{foo: string; bar: boolean}>();

Vous obtenez une frappe forte pour dispatch dans le composant, et si vous écoutez les événements foo / bar , vous obtiendrez des frappes fortes :

on:foo={e => ... // <- e is of type CustomEvent<string>

Vous obtiendrez également une bien meilleure saisie semi-automatique pour les événements maintenant. Notez cependant que vous êtes toujours autorisé à écouter d'autres événements, donc le type safety dans le sens de "n'écouter que les événements définis via createEventDispatcher " n'est toujours possible que via l'interface ComponentEvents . Mais nous prévoyons de fournir quelque chose (peut-être un attribut de balise de script) qui rendrait les événements stricts.

Documents connexes : https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#typing -component-events

Tous les 5 commentaires

La raison pour laquelle cela ne peut pas être mis en œuvre facilement est qu'il est beaucoup plus difficile de collecter tous les événements possibles que de collecter les accessoires. C'est aussi la raison pour laquelle la saisie semi-automatique ne fonctionne pas car ce sont des accessoires.

En regardant sous le capot, c'est que les accessoires sont implémentés via les accessoires jsx. Les événements ne sont pas dus aux limitations de leur collecte. Si l'utilisateur les tapait explicitement, cela pourrait être modifié. Nous ne pouvons pas marquer les événements envoyés comme "cela n'est pas conforme à la définition" bien qu'en raison des défis mentionnés.

Avoir une interface réservée est probablement la voie à suivre. Nous avons déjà pensé à cela dans le contexte des accessoires génériques. Les noms d'interface réservés pourraient être ComponentEvents , ComponentProps , ComponentSlots et ComponentDef pour saisir les trois.

Connexe #304

Obtenir l'auto-complétion avec on:<event> doit être fait différemment car sous le capot, nous utilisons JSX pour obtenir ces auto-complétions. Pour obtenir l'autocomplétion "prêt à l'emploi", nous aurions besoin d'avoir on:<event> dans le cadre des accessoires. Mais ce n'est pas possible car JSX n'autorise pas les caractères comme : dans les accessoires.
Un autre problème est que nous aurions besoin d'une manière ou d'une autre de convertir la définition du type d'événements pour ajouter le on: , ce qui ne peut pas être fait avec TypeScript pour le moment ( problème TS connexe ).

Deux solutions découlent de ces contraintes :

  • Dites aux développeurs de taper leurs événements comme __on__<eventName>: .. et nous le ferions dans le serveur de langue puis remplacerions __on__ par on: pendant la saisie semi-automatique. Cela semble sous-optimal et cassant.
  • Implémentez notre "propre" saisie semi-automatique pour cela. C'est peut-être une tâche difficile, mais cela conduirait à une solution propre.

Obtenir des erreurs « on:XXX n'existe pas » est facilement possible après la fusion de #386 grâce à une variante de la définition de la méthode $on ne revient pas à CustomEvent<any> si les utilisateurs tapent leurs événements explicitement .

Une fois que https://github.com/sveltejs/svelte/pull/5260 est publié, nous pouvons essayer de mettre à jour svelte2tsx afin qu'il recherche createEventDispatcher , regarde s'il a une annotation de type, et si oui, utilise cela pour obtenir les types appropriés.

Vous pouvez désormais profiter de la saisie createEventDispatcher introduite dans Svelte 3.25.0. Si tu fais

const dispatch = createEventDispatcher<{foo: string; bar: boolean}>();

Vous obtenez une frappe forte pour dispatch dans le composant, et si vous écoutez les événements foo / bar , vous obtiendrez des frappes fortes :

on:foo={e => ... // <- e is of type CustomEvent<string>

Vous obtiendrez également une bien meilleure saisie semi-automatique pour les événements maintenant. Notez cependant que vous êtes toujours autorisé à écouter d'autres événements, donc le type safety dans le sens de "n'écouter que les événements définis via createEventDispatcher " n'est toujours possible que via l'interface ComponentEvents . Mais nous prévoyons de fournir quelque chose (peut-être un attribut de balise de script) qui rendrait les événements stricts.

Documents connexes : https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#typing -component-events

@dummdidumm

Avez-vous une idée des raisons pour lesquelles certains événements d'écoute pour createEventDispatcher ne reçoivent pas le type ?

Exemple:

// Component Foo
const dispatchFoo = createEventDispatcher<{foo: string; bar: boolean}>();
const dispatchBar = createEventDispatcher<{bar: string; baz: string}>();

// Component Bar
// e is CustomEvent<any>
on:foo="{(e) => handleFoo(e.detail.bar)}"
// e is CustomEvent<{baz: string}>
on:bar="{(e) => handleBar(e.detail.bar)}"

Le compilateur dactylographié détecte cela comme prévu.

Changer l'ordre produit des résultats différents.

si l'ordre createEventDispatcher change, alors le compilateur dactylographié ne détecte pas l'erreur.
Il semble que seul le dernier createEventDispatcher produit le type pour l'auditeur.

// Component Foo
const dispatchBar = createEventDispatcher<{bar: string; baz: string}>();
const dispatchFoo = createEventDispatcher<{foo: string; bar: boolean}>();

// Component Bar
// e is CustomEvent<{bar: boolean}>
on:foo="{(e) => handleFoo(e.detail.bar)}"
// e is CustomEvent<any>
on:bar="{(e) => handleBar(e.detail.bar)}"

Le compilateur dactylographié ne détecte pas l'erreur puisque le type est maintenant CustomEvent<any> .

Cette page vous a été utile?
0 / 5 - 0 notes