type CallbackFn = (args: T) => void export type EventEmitter> = { on: (event: U, callback: CallbackFn) => () => void emit: (event: U, arg?: T[U]) => void removeAllListeners: (event?: U) => void } export const createEventEmitter = >(): EventEmitter => { const eventMap: Partial>>> = {} const on = (event: U, callback: CallbackFn) => { if (!eventMap[event]) { eventMap[event] = new Set>() } eventMap[event]?.add(callback) return () => eventMap[event]?.delete(callback) } const emit = (event: U, arg?: T[U]) => { eventMap[event]?.forEach((callback) => callback(arg)) eventMap['*']?.forEach((callback) => callback({ type: event, payload: arg })) } const removeAllListeners = (event?: U): void => { if (event) { eventMap[event]?.clear() } else { Object.keys(eventMap).forEach((key) => { eventMap[key as keyof T]?.clear() }) } } return { on, emit, removeAllListeners } }