Reputation: 13506
I'm trying to do this
document.addEventListener('click', (e: MouseEvent) => { ...
However, Typescript cannot know the exact event type based on event name.
'click'
=> MouseEvent
and thinks the type of e
is of type Event
. As is in definition
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface EventListener {
(evt: Event): void;
}
interface EventListenerObject {
handleEvent(evt: Event): void;
}
It obviously complains
TS2345: Argument of type '(e: MouseEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'. Type '(e: MouseEvent) => void' is not assignable to type 'EventListener'. Types of parameters 'e' and 'evt' are incompatible. Type 'Event' is missing the following properties from type 'MouseEvent': altKey, button, buttons, clientX, and 25 more.
How can I tell Typescript the e
is of type MouseEvent
? Or if I asked more generally: how to type addEventListener
properly?
Upvotes: 11
Views: 21516
Reputation:
In version 3.3.3333 they defined this way in the lib.dom.ts.
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
Where DocumentEventMap is an interface that extends GlobalEventHandlersEventMap where the click event is declared.
interface GlobalEventHandlersEventMap {
...
"click": MouseEvent;
...
}
As in the first signature, type paramater type is a key K of DocumentEventMap and ev parameter type is mapped to DocumentEventMap[K], the compiler can infer the correct type for the e in the callback function.
Upvotes: 13