import { useEffect } from "react" type UseEventListenerOptions = boolean | AddEventListenerOptions export { useEventListener } type On = { on(listener: (this: This, ev: Ev) => void, deps?: any[]): void } interface UseEventListener { ( mediaQueryList: MediaQueryList, type: K, options?: UseEventListenerOptions ): On ( window: Window, type: K, options?: UseEventListenerOptions ): On ( document: Document, type: K, options?: UseEventListenerOptions ): On ( element: HTMLElement, type: K, options?: UseEventListenerOptions ): On } const useEventListener: UseEventListener = function useEventListener( element: EventTarget, type: string, options?: UseEventListenerOptions ) { return { on(listener: (ev: any) => any, deps?: any[]) { // eslint-disable-next-line react-hooks/rules-of-hooks useEffect( () => { element.addEventListener(type, listener, options) return () => element.removeEventListener(type, listener, options) }, deps ? [element, type, ...deps] : undefined ) }, } }