I'm writing a generic useEvent hook, which basically a wrapper on top of add(remove)EventListener is useEffect. I have the below code, which throws an error
const useEvent = (
eventName: string,
cb: (e: HTMLElementEventMap[keyof HTMLElementEventMap]) => void,
options?: {
element?: EventTarget;
eventOptions?: EventListenerOptions;
dependencies?: [];
}
) => {
const node = options?.element || document;
useEffect(() => {
node.addEventListener(eventName, cb);
return () => {
node.removeEventListener(eventName, cb);
};
}, [eventName, node, cb, options?.eventOptions, ...(options?.dependencies ?? [])]);
};
export default useEvent;
Usage,
const onKeydown = (e: KeyboardEvent) => {
if (e.key === 'Escape') //do something;
}
useEvent('keydown', onKeydown, { element }); //Shows below error here on onKeydown
While using it, shows the following error on onKeydown in hook call
Argument of type '(e: KeyboardEvent) => void' is not assignable to parameter of type '(e: Event | ClipboardEvent | UIEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | ... 11 more ... | WheelEvent) => void'.
Types of parameters 'e' and 'e' are incompatible.
Type 'Event | ClipboardEvent | UIEvent | AnimationEvent | MouseEvent | InputEvent | FocusEvent | ... 11 more ... | WheelEvent' is not assignable to type 'KeyboardEvent'.
Type 'Event' is missing the following properties from type 'KeyboardEvent': altKey, charCode, code, ctrlKey, and 17 more.ts(2345)
Other approach which I tried where I'm expecting Eventtype as param:
const useEvent = <T extends Event>(
eventName: keyof HTMLElementEventMap,
handler: (e: T) => void,
options: {
element?: EventTarget;
eventOptions?: EventListenerOptions;
dependencies?: [];
}
) => {
const node = options?.element || document;
useEffect(() => {
//Shows below error here on handler
node.addEventListener(eventName, handler, options?.eventOptions);
return () => {
//Shows below error here on handler
node.removeEventListener(eventName, handler);
};
}, [eventName, node, cb, options?.eventOptions, ...(options?.dependencies ?? [])]);
};
Usage:
useEvent<KeyboardEvent>('keydown', onKeydown);
Error I got:
Argument of type '(e: T) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject | null'.
Type '(e: T) => void' is not assignable to type 'EventListener'.
Types of parameters 'e' and 'evt' are incompatible.
Type 'Event' is not assignable to type 'T'.
'Event' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Event'.ts(2345)
I'm unsure of fixes for both the cases and looking for some help! Thanks in advance.