El objetivo es detectar fácilmente errores tipográficos y ayudar a descubrir todos los posibles eventos enviados por un componente. Después de todo, no hay ninguna razón por la que las entradas (accesorios) puedan tener un contrato fuerte, pero las salidas (eventos) no. De hecho, es incluso más importante que para los accesorios, porque el envío puede ocurrir en cualquier parte del archivo, mientras que los accesorios generalmente están agrupados cuidadosamente en la parte superior.
Ahora mismo puedo escribir on:qoidfoqidjoiqsjd
muy bien.
Flex, que también tenía su compilador usaba anotaciones personalizadas para esto: https://github.com/apache/flex-sdk/blob/master/frameworks/projects/mx/src/mx/core/Container.as#L97
Quizás podríamos tener una convención especial reservada como export type Events = {name: 'eventA', data: number} | ...
Tener el TSDoc en la información sobre herramientas del lado del consumidor sería la guinda del pastel.
La razón por la que esto no se puede implementar fácilmente es que es mucho más difícil recopilar todos los eventos posibles que recopilar los accesorios. Esa también es la razón por la que el autocompletado no funciona porque son para accesorios.
Mirando bajo el capó, es que los accesorios se implementan a través de accesorios jsx. Los eventos no se deben a las limitaciones de recopilarlos. Si el usuario los escribe explícitamente, esto podría cambiarse. No podemos marcar los eventos enviados como "esto no se ajusta a la definición" debido a los desafíos mencionados.
Tener una interfaz reservada es probablemente el camino a seguir. Hemos pensado en esto antes en el contexto de los accesorios genéricos. Los nombres de interfaz reservados podrían ser ComponentEvents
, ComponentProps
, ComponentSlots
y ComponentDef
para escribir los tres.
Relacionado # 304
Obtener el autocompletado con on:<event>
tiene que hacerse de manera diferente porque, bajo el capó, usamos JSX para obtener estos autocompletados. Para obtener el autocompletado "listo para usar", necesitaríamos tener on:<event>
como parte de los accesorios. Pero esto no es posible porque JSX no permite caracteres como :
en accesorios.
Otro problema es que de alguna manera necesitaríamos convertir la definición de tipo de eventos para anteponer on:
, lo que no se puede hacer con TypeScript en este momento ( problema relacionado con TS ).
De estas limitaciones surgen dos soluciones:
__on__<eventName>: ..
y lo haríamos en el servidor de idioma y luego reemplazaríamos __on__
con on:
durante el autocompletado. Esto se siente subóptimo y quebradizo.Obtener errores " on:XXX
no existe" es fácilmente posible después de que # 386 se fusiona a través de una variación de la definición del método $on
que no retrocede a CustomEvent<any>
si los usuarios escriben sus eventos explícitamente .
Una vez que se publica https://github.com/sveltejs/svelte/pull/5260 , podemos intentar actualizar svelte2tsx
para que busque createEventDispatcher
, busque si tiene una anotación de tipo y si es así, usa eso para obtener los tipos adecuados.
Ahora puede aprovechar la escritura createEventDispatcher
introducida en Svelte 3.25.0. Si lo haces
const dispatch = createEventDispatcher<{foo: string; bar: boolean}>();
Obtiene una escritura fuerte para dispatch
dentro del componente, y si escucha los eventos foo
/ bar
, obtendrá una escritura sólida:
on:foo={e => ... // <- e is of type CustomEvent<string>
También obtendrá una función de autocompletado mucho mejor para los eventos ahora. Sin embargo, tenga en cuenta que todavía puede escuchar otros eventos, por lo que escribir seguridad en el sentido de que "solo escuchar eventos definidos a través de createEventDispatcher
" solo es posible a través de la interfaz ComponentEvents
. Pero planeamos proporcionar algo (tal vez un atributo de etiqueta de script) que haría que los eventos fueran estrictos.
Documentos relacionados: https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#typing -component-events
@dummdidumm
¿Alguna idea sobre por qué algunos eventos de escucha por createEventDispatcher
no reciben el tipo?
Ejemplo:
// 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)}"
El compilador de mecanografiado detecta esto como se esperaba.
Cambiar el orden produce resultados diferentes.
si cambia el orden createEventDispatcher
, entonces el compilador de mecanografiado no detecta el error.
Parece que solo el último createEventDispatcher
produce el tipo para el oyente.
// 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)}"
El compilador de mecanografiado no detecta el error ya que el tipo ahora es CustomEvent<any>
.
Comentario más útil
Ahora puede aprovechar la escritura
createEventDispatcher
introducida en Svelte 3.25.0. Si lo hacesObtiene una escritura fuerte para
dispatch
dentro del componente, y si escucha los eventosfoo
/bar
, obtendrá una escritura sólida:También obtendrá una función de autocompletado mucho mejor para los eventos ahora. Sin embargo, tenga en cuenta que todavía puede escuchar otros eventos, por lo que escribir seguridad en el sentido de que "solo escuchar eventos definidos a través de
createEventDispatcher
" solo es posible a través de la interfazComponentEvents
. Pero planeamos proporcionar algo (tal vez un atributo de etiqueta de script) que haría que los eventos fueran estrictos.Documentos relacionados: https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#typing -component-events