Javascript Typescript:区分HtmleElement和x27;s和SVGElement';s addEventListener

Javascript Typescript:区分HtmleElement和x27;s和SVGElement';s addEventListener,javascript,typescript,addeventlistener,Javascript,Typescript,Addeventlistener,我正在编写一个类,该类可以接受HTMLElement或SVGElement,并希望使用在这两种类型上具有相同签名的addEventListener函数绑定和事件。 我在下面隔离了一个测试用例 我的问题:是否可以在不使用instanceof的情况下为eventListener事件参数获取正确的类型 类型HTMLOSVGElement=HTMLElement | SVGEElement; 功能测试(){ const htmlEl=document.querySelector('div'); con

我正在编写一个类,该类可以接受
HTMLElement
SVGElement
,并希望使用在这两种类型上具有相同签名的
addEventListener
函数绑定和事件。 我在下面隔离了一个测试用例

我的问题:是否可以在不使用
instanceof
的情况下为
eventListener
事件
参数获取正确的类型


类型HTMLOSVGElement=HTMLElement | SVGEElement;
功能测试(){
const htmlEl=document.querySelector('div');
const svgEl=document.querySelector('svg');
const randomEl:HTMLorSVGElement | null=Math.random()>0.5?htmlEl:svgEl;
函数eventListener(事件:MouseEvent){
console.log(event.clientX);
}
/*
这种用法会产生以下错误
错误:(12,39)TS2345:类型为“(event:MouseEvent)=>void”的参数不能分配给类型为“EventListenerOrEventListenerObject”的参数。
类型“(event:MouseEvent)=>void”不可分配给类型“EventListener”。
参数“event”和“evt”的类型不兼容。
类型“Event”缺少类型“MouseeEvent”中的以下属性:altKey、button、buttons、clientX等。
*/
randomEl?.addEventListener('click',eventListener');
/*
这不会产生错误
*/
if(HtmleElement的随机事件实例){
randomEl.addEventListener('click',eventListener);
}else if(SVGElement的随机事件实例){
randomEl.addEventListener('click',eventListener);
}
}

发生这种情况的原因是,当我们将设置为true时,TypeScript编译器会感到困惑。将strict设置为true也会设置此标志

正如错误消息所说,编译器对于是否可以将eventListener函数(MouseEvent->void)分配给eventListener类型感到困惑,尽管它完全能够在不太复杂的场景中处理语法

有一个简单的变通方法可以使代码编译并工作:

randomEl?.addEventListener('click', eventListener as EventListener);
或者,我们可以使用tsconfig中的
“strictFunctionTypes”:false关闭故障标志

我已经进行了更新,因此它可以将strict设置为true,尽管我认为CodePen站点实际上不允许您设置strict标志。如果您在本地复制代码,它应该可以工作


有一行与此相关(我从哪里得到了答案!)。

我不知道为什么会在这里出现错误,因为行
randomEl?.addEventListener('click',eventListener')在TypeScript 3.7中运行良好。。它触发事件并显示所使用的是HtmleElement还是SVGElement。我正在运行TS 4.0.5。您的代码笔可以工作,但是将您的示例复制到我的项目中,甚至是使用TS 3.7的新项目也会产生相同的错误。似乎在
tsconfig.json
中将
strict
设置为
false
可以进行编译,但这并不理想。在原始代码中,我从
EventListener
强制转换中提取了测试用例,这会导致丢失事件参数的类型(我需要),但也可以通过第二次强制转换来解决。看起来这是最干净的解决方案。