Language-tools: 讨论:我们如何键入组件支持的事件

创建于 2020-08-05  ·  5评论  ·  资料来源: sveltejs/language-tools

目标是轻松捕获拼写错误并帮助发现组件调度的所有可能事件。 毕竟,没有理由为什么输入(道具)可以有一个强大的契约,而输出(事件)却没有。 事实上,它甚至比 props 更重要,因为调度可以发生在文件中的任何地方,而 props 通常整齐地聚集在一起是顶部。

现在我可以输入on:qoidfoqidjoiqsjd就好了。

Flex,它的编译器也为此使用了自定义注释: https :

也许我们可以有一个特殊的、保留的约定,如export type Events = {name: 'eventA', data: number} | ...
将 TSDoc 保留在消费者端的工具提示上将是锦上添花。

enhancement

最有用的评论

您现在可以利用 Svelte 3.25.0 中引入的createEventDispatcher类型。 如果你这样做

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

您在组件中获得了dispatch强类型,如果您监听foo / bar事件,您将获得强类型:

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

您现在还将获得更好的事件自动完成功能。 但是请注意,您仍然可以侦听其他事件,因此“仅侦听通过createEventDispatcher定义的事件”意义上的类型安全仍然只能通过ComponentEvents接口实现。 但是我们计划提供一些东西(可能是一个脚本标签属性)来使事件变得严格。

相关文档: https :

所有5条评论

之所以不能轻易实现,是因为收集所有可能的事件比收集道具要困难得多。 这也是自动完成不起作用的原因,因为这些是用于道具的。

深入了解 props 是通过 jsx props 实现的。 事件不是因为收集它们的限制。 如果用户将明确键入它们,则可以更改。 由于提到的挑战,我们不能将调度的事件标记为“这不符合定义”。

保留接口可能是前进的方向。 我们之前在泛型 props 的上下文中考虑过这个问题。 保留的接口名称可以是ComponentEventsComponentPropsComponentSlotsComponentDef用于键入所有三个。

相关 #304

使用on:<event>获得自动补全必须以不同的方式完成,因为在幕后我们使用 JSX 来获得这些自动补全。 为了让自动完成“开箱即用”,我们需要将on:<event>作为道具的一部分。 但这是不可能的,因为 JSX 不允许在 props 中使用像:这样的字符。
另一个问题是我们需要以某种方式转换事件类型定义以添加on: ,目前无法使用 TypeScript 完成(相关 TS 问题)。

这些约束产生了两种解决方案:

  • 告诉开发人员输入他们的事件,如__on__<eventName>: .. ,我们会在语言服务器中然后在自动完成期间用on:替换__on__ 。 这感觉不理想和脆弱。
  • 为此实现我们的“自己的”自动完成。 这可能是一项艰巨的任务,但会导致一个干净的解决方案。

通过$on方法定义的变体合并 #386 后,很容易出现“ on:XXX不存在” 错误,如果用户明确键入他们的事件,则不会回退到CustomEvent<any> .

一旦https://github.com/sveltejs/svelte/pull/5260发布,我们可以尝试更新svelte2tsx以便它搜索createEventDispatcher ,查看它是否有类型注释,以及如果是,则使用它来获取正确的类型。

您现在可以利用 Svelte 3.25.0 中引入的createEventDispatcher类型。 如果你这样做

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

您在组件中获得了dispatch强类型,如果您监听foo / bar事件,您将获得强类型:

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

您现在还将获得更好的事件自动完成功能。 但是请注意,您仍然可以侦听其他事件,因此“仅侦听通过createEventDispatcher定义的事件”意义上的类型安全仍然只能通过ComponentEvents接口实现。 但是我们计划提供一些东西(可能是一个脚本标签属性)来使事件变得严格。

相关文档: https :

@傻瓜

关于为什么createEventDispatcher某些侦听事件没有收到类型的任何想法?

例子:

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

打字稿编译器按预期捕获了这一点。

更改顺序会产生不同的结果。

如果createEventDispatcher顺序更改,则打字稿编译器不会捕获错误。
似乎只有最后一个createEventDispatcher为侦听器生成类型。

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

打字稿编译器不会捕获错误,因为类型现在是CustomEvent<any>

此页面是否有帮助?
0 / 5 - 0 等级