Type-Safe Event Map Emitter
Bind event names to their payload types in one map so listeners and emitters are checked together and misspelled events fail to compile.
Code
type EventMap = {
login: { userId: string };
logout: { userId: string; reason: string };
error: { message: string; retryable: boolean };
};
export class TypedEmitter<M extends Record<string, unknown>> {
private handlers: { [K in keyof M]?: Array<(payload: M[K]) => void> } = {};
on<K extends keyof M>(event: K, handler: (payload: M[K]) => void): void {
(this.handlers[event] ??= []).push(handler);
}
emit<K extends keyof M>(event: K, payload: M[K]): void {
for (const handler of this.handlers[event] ?? []) handler(payload);
}
}
export const emitter = new TypedEmitter<EventMap>();Report a problem with this exampleOpens a pre-filled issue on GitHub.