类型'(e:CustomEvent)=> void'的参数不能赋值给'EventListenerOrEventListenerObject'类型的参数

Get*_*awn 13 javascript typescript

我有这个自定义事件设置,它适用于TypeScript 2.5.3,但当我更新到2.6.1我得到一个错误

window.addEventListener('OnRewards', (e: CustomEvent) => {
    // my code here
})
Run Code Online (Sandbox Code Playgroud)

[ts]类型'(e:CustomEvent)=> void'的参数不能赋值给'EventListenerOrEventListenerObject'类型的参数.

类型'(e:CustomEvent)=> void'不能分配给'EventListenerObject'类型.

类型'(e:CustomEvent)=> void'中缺少属性'handleEvent'.

我不确定该怎么做才能解决这个问题.

jca*_*alz 15

这是由于--strictFunctionTypesTypeScript v2.6中添加的编译器标志的行为.类型的函数(e: CustomEvent) => void不再被认为是有效的实例EventListener,它接受Event参数而不是a CustomEvent.

所以解决它的一种方法是关闭--strictFunctionTypes.


另一种方法是传入一个函数,该函数通过一个类型保护Event来获取然后缩小CustomEvent:

function isCustomEvent(event: Event): event is CustomEvent {
  return 'detail' in event;
}

window.addEventListener('OnRewards', (e: Event) => {
  if (!isCustomEvent(e))
    throw new Error('not a custom event');
  // e is now narrowed to CustomEvent ...
  // my code here 
})
Run Code Online (Sandbox Code Playgroud)

第三种方法是使用另一个重载addEventListener():

addEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void;
Run Code Online (Sandbox Code Playgroud)

如果type参数是已知事件类型(K extends keyof WindowEventMap)的名称"onclick",则该listener函数将期望其参数为该变窄的事件类型(WindowEventMap[K]).问题是,这"OnRewards"不是一个已知的事件类型...除非您使用声明合并使其知道:

// merge into WindowEventMap
interface WindowEventMap {
    OnRewards: CustomEvent
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您在模块内(其中包含任何export内容),请使用全局扩充:

// merge into WindowEventMap
declare global {
  interface WindowEventMap {
    OnRewards: CustomEvent
  }
}
Run Code Online (Sandbox Code Playgroud)

然后像以前一样使用您的代码:

// no error!
window.addEventListener('OnRewards', (e: CustomEvent) => {
    // my code here
})
Run Code Online (Sandbox Code Playgroud)

所以,那些是你的选择.您要选择哪一个取决于您.希望有所帮助; 祝好运!

  • +1,但我真的希望你没有从'关闭--strictFunctionTypes`开始.如此多的TS问题通过"禁用检查"来回答,如果这是标准选择,那么我们也可以放弃TS. (3认同)

Jac*_*lyn 6

jcalz的出色回答的基础上,您还可以使用类型断言使代码更简洁

window.addEventListener('OnRewards', (e: Event) => {
    const detail = (<CustomEvent>e).detail;
    ...
});
Run Code Online (Sandbox Code Playgroud)