Svelte 中 on:change 处理程序的正确 Typescript 类型

Mik*_*gan 8 typescript svelte

我有这个代码:

<select class="form-control" on:change={pathChanged}>
Run Code Online (Sandbox Code Playgroud)

的签名pathChanged是:

function pathChanged(event: { target: HTMLSelectElement }) {
Run Code Online (Sandbox Code Playgroud)

tsc当我通过using运行该命令时npm run check,出现以下错误:

Error: Type '(event: { target: HTMLSelectElement; }) => void' is not assignable to type 'FormEventHandler<HTMLSelectElement>'.
  Types of parameters 'event' and 'event' are incompatible.
    Type 'Event & { currentTarget: EventTarget & HTMLSelectElement; }' is not assignable to type '{ target: HTMLSelectElement; }'.
      Types of property 'target' are incompatible.
        Type 'EventTarget | null' is not assignable to type 'HTMLSelectElement'.
          Type 'null' is not assignable to type 'HTMLSelectElement'. (ts)

<select class="form-control" on:change={pathChanged}>
Run Code Online (Sandbox Code Playgroud)

应该有什么签名pathChanged

H.B*_*.B. 16

该事件target并不像您希望的那样具体1 。在这种情况下,我通常在函数中使用类型断言来解决这个问题。

function pathChanged(event: Event) {
   const target = event.target as HTMLSelectElement;
   // ...
}
Run Code Online (Sandbox Code Playgroud)

尽管错误指出currentTarget应该正确输入,所以使用它应该也可以工作:

function pathChanged(event: { currentTarget: HTMLSelectElement })
Run Code Online (Sandbox Code Playgroud)

如果事件具有更具体的类型Event,例如MouseEvent,可以使用以下方式组合这些类型&

function onMouseUp(event: MouseEvent & { currentTarget: HTMLSelectElement })
Run Code Online (Sandbox Code Playgroud)

1原因是大多数事件都会冒泡,并且target通常可以是带有处理程序的元素内的任何元素。currentTarget始终使用处理程序引用元素,因此可以明确键入。