Language-tools: Discussão: Como podemos digitar os eventos suportados por um componente

Criado em 5 ago. 2020  ·  5Comentários  ·  Fonte: sveltejs/language-tools

O objetivo é detectar erros de digitação facilmente e ajudar na descoberta de todos os eventos possíveis despachados por um componente. Afinal, não há razão para que as entradas (adereços) possam ter um contrato forte, mas as saídas (eventos) não. Na verdade, é ainda mais importante do que para os adereços, porque o despacho pode ocorrer em qualquer lugar no arquivo, enquanto os adereços são normalmente agrupados de forma ordenada no topo.

No momento, posso digitar on:qoidfoqidjoiqsjd muito bem.

Flex, que também teve seu compilador usado anotações personalizadas para isso: https://github.com/apache/flex-sdk/blob/master/frameworks/projects/mx/src/mx/core/Container.as#L97

Talvez pudéssemos ter uma convenção especial reservada como export type Events = {name: 'eventA', data: number} | ...
Ter o TSDoc transportado para a dica de ferramenta do lado do consumidor seria a cereja do bolo.

enhancement

Comentários muito úteis

Agora você pode aproveitar as vantagens da digitação createEventDispatcher introduzida no Svelte 3.25.0. Se você fizer

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

Você obtém uma digitação forte para dispatch dentro do componente e, se ouvir os eventos foo / bar , obterá digitações fortes:

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

Você também terá um preenchimento automático muito melhor para eventos agora. Observe, entretanto, que você ainda tem permissão para ouvir outros eventos, portanto, digite safety no sentido de "apenas ouvir eventos definidos por meio de createEventDispatcher " ainda só é possível por meio da interface ComponentEvents . Mas planejamos fornecer algo (talvez um atributo de tag de script) que tornaria os eventos restritos.

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

Todos 5 comentários

A razão pela qual isso não pode ser implementado facilmente é que é muito mais difícil coletar todos os eventos possíveis do que coletar os adereços. Essa também é a razão pela qual o preenchimento automático não funciona, porque eles são para adereços.

Olhando sob o capô, é que os adereços são implementados por meio de adereços jsx. Os eventos não ocorrem devido às limitações de sua coleta. Se o usuário os digitar explicitamente, isso pode ser alterado. Não podemos marcar os eventos despachados como "isso não está de acordo com a definição", devido aos desafios mencionados.

Ter uma interface reservada é provavelmente o caminho a seguir. Já pensamos nisso antes, no contexto de adereços genéricos. Os nomes de interface reservados podem ser ComponentEvents , ComponentProps , ComponentSlots e ComponentDef para digitar todos os três.

Relacionado # 304

Obter o preenchimento automático com on:<event> deve ser feito de maneira diferente, porque nos bastidores usamos JSX para obter esses preenchimentos automáticos. Para obter o preenchimento automático "pronto para uso", precisaríamos ter on:<event> como parte dos adereços. Mas isso não é possível porque JSX não permite caracteres como : em adereços.
Outro problema é que, de alguma forma, precisaríamos converter a definição do tipo de eventos para preceder on: , o que não pode ser feito com o TypeScript no momento ( problema relacionado ao TS ).

Duas soluções surgem dessas restrições:

  • Diga aos desenvolvedores para digitarem seus eventos como __on__<eventName>: .. e nós, no servidor de linguagem, substituiríamos __on__ por on: durante o preenchimento automático. Isso parece subótimo e frágil.
  • Implemente nosso autocompletar "próprio" para isso. Esta é possivelmente uma tarefa difícil, mas levaria a uma solução limpa.

Obter o erro " on:XXX does not exist" é facilmente possível após # 386 ser mesclado por meio de uma variação da definição do método $on , sem cair para CustomEvent<any> se os usuários digitarem seus eventos explicitamente .

Assim que https://github.com/sveltejs/svelte/pull/5260 for lançado, podemos tentar atualizar svelte2tsx para que procure createEventDispatcher , veja se tem uma anotação de tipo e em caso afirmativo, usa isso para obter os tipos adequados.

Agora você pode aproveitar as vantagens da digitação createEventDispatcher introduzida no Svelte 3.25.0. Se você fizer

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

Você obtém uma digitação forte para dispatch dentro do componente e, se ouvir os eventos foo / bar , obterá digitações fortes:

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

Você também terá um preenchimento automático muito melhor para eventos agora. Observe, entretanto, que você ainda tem permissão para ouvir outros eventos, portanto, digite safety no sentido de "apenas ouvir eventos definidos por meio de createEventDispatcher " ainda só é possível por meio da interface ComponentEvents . Mas planejamos fornecer algo (talvez um atributo de tag de script) que tornaria os eventos restritos.

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

@dummdidumm

Alguma idéia de por que alguns eventos de escuta de createEventDispatcher não recebem o tipo?

Exemplo:

// 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)}"

O compilador de texto digitado detecta isso conforme o esperado.

Alterar a ordem produz resultados diferentes.

se a ordem createEventDispatcher muda, então o compilador de texto digitado não detecta o erro.
Parece que apenas o último createEventDispatcher produz o tipo para o ouvinte.

// 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)}"

O compilador de texto digitado não detecta o erro, pois o tipo agora é CustomEvent<any> .

Esta página foi útil?
0 / 5 - 0 avaliações