简体   繁体   中英

How to handle 'Event' type and 'CustomEvent' type on eventListeners, in Typescript

I m dispatching a CustomEvent with a detail property, in my app, and i grab it into another app, with an eventListener.

I m struggling with typescript to make it work smooth, but whatever i tried so far i get on an obstacle.

so the eventlistener is like so( all is happening into a react global component ):

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

And further down, i have the callEvent method like so:

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

.......
}

All the long error 'Typescript' messages are happening when i try to change the any type, to a meaningfull type, for the callEvent func, like:

Version 1:

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

Version 2: .

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

.....
}

Res:

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

Version 3:

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

Res: .

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.

And some other versions but in vain. if you guys have any idea that i ll be able to replace, successfully, callEvent: any to a proper type , please give a shout.

It would also be helpful if there are any plugins or other editors that can identify types and suggest. Thanks.

Ok, it worked by adding a type cast on the eventListener, i share it for anyone who ll come up across with similar siuation.

So adding as (e: Event) => void at the end like so:

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

It's because TypeScript doesn't know your custom event exists.

The first overload basically says it expects your event to be part of keyof WindowEventMap , which you can accomplish by 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) => {
    
});

The second overload mentions if you don't augment WindowEventMap , your argument needs to extend 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) => {
    
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM