export type EventType = string | symbol; export type Handler = (event: T) => void; export type WildcardHandler> = ( type: keyof T, event: T[keyof T] ) => void; export type EventHandlerList = Array>; export type WildCardEventHandlerList> = Array< WildcardHandler >; export type EventHandlerMap> = Map< keyof Events | '*', EventHandlerList | WildCardEventHandlerList >; export interface Emitter> { all: EventHandlerMap; on(type: Key, handler: Handler): void; on(type: '*', handler: WildcardHandler): void; off( type: Key, handler?: Handler ): void; off(type: '*', handler: WildcardHandler): void; emit(type: Key, event: Events[Key]): void; emit( type: undefined extends Events[Key] ? Key : never ): void; } export default function mitt>( all?: EventHandlerMap ): Emitter { type GenericEventHandler = | Handler | WildcardHandler; all = all || new Map(); return { all, on(type: Key, handler: GenericEventHandler) { const handlers: Array | undefined = all!.get(type); if (handlers) { handlers.push(handler); } else { all!.set(type, [handler] as EventHandlerList); } }, off(type: Key, handler?: GenericEventHandler) { const handlers: Array | undefined = all!.get(type); if (handlers) { if (handler) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); } else { all!.set(type, []); } } }, emit(type: Key, evt?: Events[Key]) { let handlers = all!.get(type); if (handlers) { (handlers as EventHandlerList) .slice() .map((handler) => { handler(evt!); }); } handlers = all!.get('*'); if (handlers) { (handlers as WildCardEventHandlerList) .slice() .map((handler) => { handler(type, evt!); }); } } }; }