最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

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.

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.

Share Improve this question asked Jul 29, 2021 at 16:12 Theo ItzarisTheo Itzaris 4,6815 gold badges44 silver badges75 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 15

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) => {
    
});

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);
发布评论

评论列表(0)

  1. 暂无评论