// https://stackoverflow.com/a/68783088/1133344 interface MolinPasteDetail { text: string; timestamp: string; } interface CustomEventMap { 'molin:paste': CustomEvent; } declare global { interface Document { // adds definition to Document, but you can do the same with HTMLElement addEventListener(type: K, listener: (this: Document, ev: CustomEventMap[K]) => void): void; dispatchEvent(ev: CustomEventMap[K]): void; } } export {}; // keep that for TS compiler // function onCustomEvent(event: CustomEvent){ // this.[...] // this is Document // event.detail ... //is your CustomParams type. // } // document.addEventListener('anothercustomevent', onCustomEvent); // Three small changes for completeness sake. // 1) The addEventListener declaration should include the third options parameter: options?: boolean | AddEventListenerOptions. // 2) The return type of the listener param should be any to match the one in lib.dom.d.ts // 3) You should include the declaration for removeEventListener (including the above points): removeEventListener( type: K, listener: (this: HTMLElement, ev: CustomEventMap[K]) => any, options?: boolean | EventListenerOptions, ): void;