ts-04-event-emitter
1.000
Proposed solution
```typescript
export class EventEmitter<Events extends Record<string, unknown[]>> {
private listeners: { [K in keyof Events]: ((...args: Events[K]) => void)[] } = {};
on<E extends keyof Events>(event: E, fn: (...args: Events[E]) => void): () => void {
this.listeners[event] = this.listeners[event] || [];
this.listeners[event].push(fn);
return () => this.off(event, fn);
}
off<E extends keyof Events>(event: E, fn: (...args: Events[E]) => void): void {
if (!this.listeners[event]) return;
const index = this.listeners[event].indexOf(fn);
if (index !== -1) {
this.listeners[event].splice(index, 1);
}
}
emit<E extends keyof Events>(event: E, ...args: Events[E]): void {
if (!this.listeners[event]) return;
this.listeners[event].forEach((listener) => listener(...args));
}
}
```Test output (stdout)
TAP version 13 # Subtest: calls a registered listener with args ok 1 - calls a registered listener with args --- duration_ms: 0.611027 type: 'test' ... # Subtest: multiple listeners fire in registration order ok 2 - multiple listeners fire in registration order --- duration_ms: 0.078951 type: 'test' ... # Subtest: passes multiple typed args ok 3 - passes multiple typed args --- duration_ms: 0.053001 type: 'test' ... # Subtest: returned unsubscribe removes the listener ok 4 - returned unsubscribe removes the listener --- duration_ms: 0.05584 type: 'test' ... # Subtest: off removes a specific listener, leaving others ok 5 - off removes a specific listener, leaving others --- duration_ms: 3.326904 type: 'test' ... # Subtest: emitting an event with no listeners is a no-op ok 6 - emitting an event with no listeners is a no-op --- duration_ms: 0.100771 type: 'test' ... # Subtest: off on an unregistered listener is a no-op ok 7 - off on an unregistered listener is a no-op --- duration_ms: 0.04359 type: 'test' ... # Subtest: the same function registered twice fires twice ok 8 - the same function registered twice fires twice --- duration_ms: 0.0605 type: 'test' ... 1..8 # tests 8 # suites 0 # pass 8 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 77.285742
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.