I am writing a method in my library that can register a bunch of user-provided event listeners. Here is a simplified example:
function registerEventListeners(events: Record<string, EventListenerOrEventListenerObject>): void {
for (const [name, handler] of Object.entries(events)) {
window.addEventListener(name, handler)
}
}
const customEvents = {
keydown: (e: KeyboardEvent) => {
if (e.key === "Enter") {
// ...
}
}
}
registerEventListeners(customEvents)
TypeScript is giving me this error at the call site of registerEventListeners...
~ 1. Argument of type '{ keydown: (e: KeyboardEvent) => void; }' is not assignable to parameter of type 'Record<string, EventListenerOrEventListenerObject>'.
~ Property 'keydown' is incompatible with index signature.
~ Type '(e: KeyboardEvent) => void' is not assignable to type 'EventListenerOrEventListenerObject'.
~ Type '(e: KeyboardEvent) => void' is not assignable to type 'EventListener'.
~ Types of parameters 'e' and 'evt' are incompatible.
~ Type 'Event' is missing the following properties from type 'KeyboardEvent': altKey, charCode, code, ctrlKey, and 17 more.
The EventListenerOrEventListenerObject generic seems to be unable to guarantee that my keydown event handler will receive the correct event type. So what is the correct way to type this code?
Event, while your function expects aKeyboardEvent. Because you have typed theeventsparameter as a record of event listeners that take any events, you have no safety that another kind of Event will be passed to your keydown handler.