A plain EventEmitter accepts any string as an event name and any value as the payload — no compile-time safety. TypeScript generics fix that:
type Events = {
login: { userId: string };
logout: void;
error: Error;
};
const emitter = new TypedEventEmitter<Events>();
emitter.on('login', ({ userId }) => console.log(userId)); // ✅ payload typed
emitter.emit('typo', {}); // ❌ TypeScript Error: 'typo' not in Events
emitter.emit('login', 42); // ❌ TypeScript Error: payload must be { userId: string }Complete the TypedEventEmitter<TEvents> class:
| Method | Behaviour |
|---|---|
on(event, listener) | Subscribe — returns this for chaining |
off(event, listener) | Unsubscribe exactly that listener function |
emit(event, payload) | Call all subscribers for this event with the payload |
once(event, listener) | Subscribe for a single emission, then auto-remove |
Sample tests