reactjs - Typescript addEventListener para keydown da error
Quiero eliminar y agregar escuchadores de eventos a elementos HTML que pueden recibir el foco (en este caso botones), pero estoy viendo un error de TypeScript en las líneas de código que agregan y eliminan el escuchador de eventos:
focusableElements.forEach((el) => {
el.removeEventListener('keydown', focus);
el.addEventListener('keydown', focus);
});
focus acepta un KeyboardEvent de la siguiente manera
const focus = (evt: KeyboardEvent) => {
.... in here we have code that uses evt.key and evt.shiftKey
}
este es el error exacto que estoy viendo
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.
Intenté cambiar KeyboardEvent a Event, pero eso provoca otros errores dentro de focus debido a que estamos usando evt.key y evt.shiftKey.
Respuesta #1
La razón de este error es que las definiciones existentes para EventListeners son muy amplias y genéricas en el sentido de que las sobrecargas proporcionadas no lo definen para todos los posibles tipos de eventos, como Mouse, Keyboard, etc.
¡Pero podemos crear nuestra propia sobrecarga para esto basada en nuestros requisitos, por lo tanto, para este caso de uso, esto lo resolvería!
Ahora hemos creado dos sobrecargas más para manejar nuestro escenario especial.
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
}
Patio de código
