type AbstractEventMap = { [eventName: string]: any }; type Listener = ( event: M[K] ) => any; export class EventListenerManager { private handlers: { [eventName: string]: Listener[] } = {}; public addEventListener( type: K, listener: Listener ) { if (!this.handlers[type]) { this.handlers[type] = []; } this.handlers[type].push(listener); } public removeEventListener( type: K, listener: Listener ) { const idx = this.handlers[type].indexOf(listener); if (idx >= 0) { this.handlers[type].splice(idx, 1); } } public emitEvent(type: K, payload: M[K]) { for (const handler of this.handlers[type]) { handler(payload); } } }