我正在尝试用 Svelte TypeScript 构建一个简单的表单。
我的 on:submit 看起来像这样:
<form on:submit={onSubmit}>
,我的 onSubmit 函数定义为:
const onSubmit = (event: HTMLFormElement) => {
event.preventDefault();
dispatch("addPerson", person);
person = {
name: "",
isOwed: 0,
};
};
通过这段代码,我遇到了 TypeScript 问题:
类型“(event: HTMLFormElement) => void”不可分配给类型“EventHandler
”。 参数“event”和“event”的类型不兼容。
我知道传递给 onSubmit 的事件具有类型
EventHandler<Event, HTMLFormElement>
,并且我的函数只期望 HTMLFormElement,但我无法期望整个 EventHandler 对象。我怎样才能实现这个目标?
事件类型是
SubmitEvent
。
function handleSubmit(e: SubmitEvent) {
const formData = new FormData(e.target as HTMLFormElement)
}
<form on:submit|preventDefault={handleSubmit}>
试试这个。
<script lang="ts">
const handleSubmit: svelte.JSX.EventHandler<Event, HTMLFormElement> = () => {
}
</script>
<form on:submit|preventDefault={handleSubmit}>
</form>
event
参数是 Event
,而不是 HTMLFormElement
HTML 节点。因此,您可以将 event: HTMLFormElement
替换为 event: Event
甚至更好(按照 TypeScript 的建议):event: EventHandler<Event, HTMLFormElement>
。
正如@coldbreathe 建议在另一个答案中一样,最直接的方法似乎是注释处理函数:
<script lang="ts">
import type { EventHandler } from "svelte/elements";
const handleSubmit: EventHandler<SubmitEvent, HTMLFormElement> =
function (event) {
const data = new FormData(event.currentTarget);
// event.currentTarget will have type HTMLFormElement here
};
</script>
<form on:submit|preventDefault={handleSubmit}>
<!-- ... -->
</form>
EventHandler<E, T>
这里基本上是说event
将具有类型E
并且event.currentTarget
将具有类型T
。这是实际的定义:
type EventHandler<E extends Event = Event, T extends EventTarget = Element> = (
event: E & { currentTarget: EventTarget & T }
) => any;
currentTarget
而不仅仅是target
?EventHandler
注释不会改变event.target
的类型——这是因为它可能从任何其他类型的元素中冒泡。特别是对于 SubmitEvent
来说,这不应该发生,但对于其他事件来说这是可能的。
经验法则:为了保持一致性,只需使用
currentTarget
,除非出于某种原因需要 target
。