【问题标题】:How to handle 'Event' type and 'CustomEvent' type on eventListeners, in Typescript如何在 Typescript 中处理 eventListeners 上的“Event”类型和“CustomEvent”类型
【发布时间】:2021-07-29 16:12:04
【问题描述】:

我在我的应用程序中调度一个带有detail 属性的CustomEvent,然后我将它抓取到另一个应用程序中,带有一个事件监听器。

我正在努力使用 typescript 以使其顺利运行,但到目前为止,无论我尝试什么,都会遇到障碍。

所以 eventlistener 就像这样(所有都发生在一个 react 全局组件中):

window.addEventListener('my-custom-event', this.callEvent);

再往下,我有这样的callEvent 方法:

  callEvent: any = (e: CustomEvent) => {
const {
  detail,
} = e;

.......
}

当我尝试将 any 类型更改为有意义的类型时,所有长错误“Typescript”消息都发生在 callEvent func 中,例如:

版本 1:

callEvent: (e: CustomEvent) => void = (e: CustomEvent) => {...}

第 2 版:

callEvent(e: CustomEvent) {
const {
  detail,
} = e;

.....
}

回复:

No overload matches this call.
Overload 1 of 2, '(type: keyof WindowEventMap, listener: (this: Window, ev: Event | 
UIEvent | BeforeUnloadEvent | FocusEvent | MouseEvent | ... 21 more ... | 
PromiseRejectionEvent) => any, options?: boolean | ... 1 more ... | undefined): 
 void', gave the following error.
Argument of type '"my-custom-event"' is not assignable to parameter of type 
'keyof WindowEventMap'.
 Overload 2 of 2, '(type: string, listener: EventListenerOrEventListenerObject, 
 options?: boolean | AddEventListenerOptions | undefined): void', gave the following 
 error.
 Argument of type '(e: CustomEvent<any>) => void' is not assignable to parameter of 
 type 'EventListenerOrEventListenerObject'.
  Type '(e: CustomEvent<any>) => void' is not assignable to type 'EventListener'.
    Types of parameters 'e' and 'evt' are incompatible.
      Type 'Event' is missing the following properties from type 'CustomEvent<any>': 
 detail, initCustomEvent

版本 3:

callEvent: (e: Event) => void = (e: Event) => {
const detail = (<CustomEvent>e).detail; // it thinks this is JSX
...
}

回复:

var CustomEvent: {
new <T>(typeArg: string, eventInitDict?: CustomEventInit<T> | undefined): 
 CustomEvent<T>;
prototype: CustomEvent<any>;
}
JSX element 'CustomEvent' has no corresponding closing tag.ts(17008)
'React' refers to a UMD global, but the current file is a module. Consider adding an 
import instead.ts(2686)
'CustomEvent' cannot be used as a JSX component.
Its instance type 'CustomEvent<unknown>' is not a valid JSX element.
Type 'CustomEvent<unknown>' is missing the following properties from type 
'ElementClass': render, context, setState, forceUpdate, and 3 more.

还有其他一些版本,但都是徒劳的。 如果你们有任何想法我可以成功地将callEvent: any替换为正确的类型,请大声疾呼。

如果有任何插件或其他编辑器可以识别types 并提出建议,那也会很有帮助。 谢谢。

【问题讨论】:

    标签: javascript reactjs typescript events


    【解决方案1】:

    好的,它通过在 eventListener 上添加类型转换来工作,我将它分享给任何遇到类似情况的人。

    所以像这样在末尾添加as (e: Event) =&gt; void

    window.addEventListener('my-custom-event', this.callEvent as (e: Event) => void);
    

    【讨论】:

      【解决方案2】:

      这是因为 TypeScript 不知道你的自定义事件存在。

      第一个重载基本上表示它希望您的事件成为keyof WindowEventMap 的一部分,您可以通过augmenting 完成WindowEventMap

      declare global {
          interface WindowEventMap {
              'my-custom-event': CustomEvent;
          }
      }
      
      // Won't error anymore (unless you misspell your event, of course)
      window.addEventListener('my-custom-event', (event: CustomEvent) => {
          
      });
      

      第二个重载提到如果你不扩充WindowEventMap,你的论点需要扩充Event

      class MyCustomEvent extends Event {}
      
      // No error either, even though 'my-other-custom-event' is completely new
      window.addEventListener('my-other-custom-event', (event: MyCustomEvent) => {
          
      });
      

      【讨论】:

      • 如果我有class Foo extends EventTarget怎么办?如何将此 EventMap 事物添加到 Foo
      猜你喜欢
      • 1970-01-01
      • 2017-12-28
      • 2021-11-27
      • 1970-01-01
      • 2017-10-27
      • 2021-01-26
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多