我想删除和添加事件侦听器到HTML元素,可以集中(在本例中为按钮),但我看到添加和删除事件侦听器的代码行上出现打字错误:
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.key
和evt.shiftKey
,这在焦点内带来了其他错误。
这个错误背后的原因是EventListeners
的现有定义在某种意义上是非常广泛和通用的,所提供的重载没有为所有可能的事件类型(如Mouse
,Keyboard
等)定义它。
但是我们可以根据我们的需求创建自己的重载因此,对于这个用例,这将解决它!
现在我们已经创建了两个重载来处理我们的特殊场景。
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
}
操场代码