← run

ts-04-event-emitter

1.000
8/8 tests· typing

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.