TypeScript 添加事件监听器设置事件类型

11

我正在尝试做这件事

document.addEventListener('click', (e: MouseEvent) => { ...

然而,Typescript无法根据事件名称确定确切的事件类型。

'click' => MouseEvent

并且认为e的类型是Event类型。这就是定义中的情况。

declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
    
interface EventListener {
    (evt: Event): void;
}
    
interface EventListenerObject {
    handleEvent(evt: Event): void;
}

显然它抱怨

TS2345:'(e: MouseEvent) => void'的类型参数不能赋值给类型参数'EventListenerOrEventListenerObject'。 类型'(e: MouseEvent) => void'不能分配给类型'EventListener'。 参数'e'和'evt'的类型不兼容。 类型'Event'缺少类型'MouseEvent'的以下属性:altKey,button,buttons,clientX和25个更多。

我如何告诉TypeScript,eMouseEvent类型?或者更一般地说:如何正确为addEventListener编写类型?

1个回答

12
在版本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,其中声明了click事件。

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

就像第一个签名一样,type参数类型是DocumentEventMap的关键字K,而ev参数类型被映射到DocumentEventMap[K],编译器可以推断回调函数中的e的正确类型。


1
看起来很酷,但似乎他们只在 document 上添加了它 https://github.com/Microsoft/TypeScript/blob/b145eaf160e6b2729aaacb89856bc2346f85ac4c/lib/lib.dom.d.ts#L4571 然而,由于它在 Element 上尚未实现,所以最佳答案似乎是顶部的答案。谢谢! - simPod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接