simPod
simPod

Reputation: 13506

Typescript addEventListener set event type

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

Answers (1)

user11010433
user11010433

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

Related Questions