export type EventMap = Record; type EventKey = string & keyof T; type EventReceiver = (params: T) => void; export interface Emitter { on>(eventName: K, fn: EventReceiver): void; off>(eventName: K, fn: EventReceiver): void; emit>(eventName: K, params: T[K]): void; } export interface Listener { on>(eventName: K, fn: EventReceiver): void; off>(eventName: K, fn: EventReceiver): void; } export function makeEmitter(): Emitter { const listeners: Partial< Record, ((...params: any[]) => void)[]> > = {}; return { on(eventName, fn) { if (!listeners[eventName]) listeners[eventName] = []; listeners[eventName]?.push(fn); }, off(eventName, fn) { listeners[eventName] = listeners[eventName]?.filter((v) => v !== fn) ?? []; }, emit(eventName, params) { (listeners[eventName] ?? []).forEach((fn) => fn(params)); }, }; }