精简表单:提交类型TypeScript

问题描述 投票:0回答:4

我正在尝试用 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 对象。我怎样才能实现这个目标?

typescript svelte
4个回答
13
投票

事件类型是

SubmitEvent

function handleSubmit(e: SubmitEvent) {
 const formData = new FormData(e.target as HTMLFormElement)
}
<form on:submit|preventDefault={handleSubmit}>

4
投票

试试这个。

<script lang="ts">    
      const handleSubmit: svelte.JSX.EventHandler<Event, HTMLFormElement> = () => {

      }
</script>

<form on:submit|preventDefault={handleSubmit}>

</form>

1
投票

event
参数是
Event
,而不是
HTMLFormElement
HTML 节点。因此,您可以将
event: HTMLFormElement
替换为
event: Event
甚至更好(按照 TypeScript 的建议):
event: EventHandler<Event, HTMLFormElement>


0
投票

正如@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

© www.soinside.com 2019 - 2024. All rights reserved.