Typescript addEventListener to keydown 给出错误

IT技术 reactjs typescript
2022-07-16 01:47:27

我想删除事件侦听器并将其添加到可以聚焦的 HTML 元素(在本例中为按钮),但我在添加和删除事件侦听器的代码行上看到了typescript错误:

  focusableElements.forEach((el) => {
      el.removeEventListener('keydown', focus); 
      el.addEventListener('keydown', focus);
  });

focus 像这样接受一个 KeyboardEvent

const focus = (evt: KeyboardEvent) => {
    .... in here we have code that uses evt.key and evt.shiftKey
}

这是我看到的确切错误

No overload matches this call.
  Overload 1 of 2, '(type: keyof ElementEventMap, listener: (this: Element, ev: Event) => any, options?: boolean | EventListenerOptions | undefined): void', gave the following error.
    Argument of type '"keydown"' is not assignable to parameter of type 'keyof ElementEventMap'.
  Overload 2 of 2, '(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void', gave the following error.
    Argument of type '(evt: KeyboardEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'.
      Type '(evt: KeyboardEvent) => void' is not assignable to type 'EventListener'.
        Types of parameters 'evt' and 'evt' are incompatible.
          Type 'Event' is missing the following properties from type 'KeyboardEvent': altKey, charCode, code, ctrlKey, and 17 more.

我尝试更改KeyboardEvent为,Event但由于我们使用evt.keyevt.shiftKey.

1个回答

这个错误背后的原因是现有的定义EventListeners在某种意义上非常广泛和通用,提供的重载没有为所有可能的事件类型定义它,例如MouseKeyboard等。

但是我们可以根据我们的要求为此创建自己的重载,因此对于这个用例,这将解决它!

现在我们已经创建了另外两个重载来处理我们的特殊情况。

let focusableElements: Element[] = [];

interface Element {
  removeEventListener(type: 'keyup' | 'keydown', listener: (event: KeyboardEvent) => any, options?: boolean | EventListenerOptions): void;
  addEventListener(type: 'keyup' | 'keydown', listener: (event: KeyboardEvent) => any, options?: boolean | EventListenerOptions): void;

}

focusableElements.forEach((el) => {
      el.removeEventListener('keydown', focus_);
      el.addEventListener('keydown', focus_);
  });


const focus_ = (evt: KeyboardEvent) => {
    evt.key // works fine
    evt.shiftKey //perfectly fine
}


代码游乐场