首页 > 解决方案 > 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?

标签: typescript

解决方案


在版本 3.3.3333 中,他们在 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;

其中DocumentEventMap是一个接口,它扩展 了声明单击事件的GlobalEventHandlersEventMap 。

interface GlobalEventHandlersEventMap {
    ...
    "click": MouseEvent;
    ...
}

和第一个签名一样,type参数type是DocumentEventMap的 key Kev参数type映射到DocumentEventMap [ K ],编译器可以推断出回调函数中e的正确类型。


推荐阅读