A standard EventEmitter accepts string events and any payloads. A TypedEmitter uses a generic EventMap to enforce correct types per event:
type AppEvents = {
'user:login': { userId: string; at: Date };
'challenge:solved': { challengeId: string; score: number };
'error': Error;
};
const emitter = new TypedEmitter<AppEvents>();
// ✅ TypeScript enforces the correct payload type:
emitter.on('user:login', ({ userId, at }) => { ... });
emitter.emit('user:login', { userId: 'u_1', at: new Date() });
// ❌ TypeScript errors:
emitter.on('unknown-event', () => {}); // not in AppEvents
emitter.emit('user:login', { message: 'hello' }); // wrong payload shapeK extends keyof TMapon<K extends keyof TMap>(event: K, handler: (payload: TMap[K]) => void): this
// ↑ binds K to a valid event name
// ↑ payload type is derived from the event name| Method | Behavior |
|---|---|
on(event, handler) | Subscribe (chainable) |
off(event, handler) | Unsubscribe (chainable) |
emit(event, payload) | Call all handlers |
once(event, handler) | Subscribe, auto-unsubscribe after first call |
Sample tests