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.
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:
__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.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>
.
Comentários muito úteis
Agora você pode aproveitar as vantagens da digitação
createEventDispatcher
introduzida no Svelte 3.25.0. Se você fizerVocê obtém uma digitação forte para
dispatch
dentro do componente e, se ouvir os eventosfoo
/bar
, obterá digitações fortes: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 interfaceComponentEvents
. 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