前置知识: TypeScript

类型安全的事件系统

00:00
1 min Advanced 2026/6/14

构建类型安全的事件发射器

1. 基础事件系统

type EventMap = {
  click: { x: number; y: number };
  change: { value: string };
  submit: {};
};

class EventEmitter<Events extends Record<string, any>> {
  private listeners = new Map<keyof Events, Set<Function>>();

  on<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): () => void {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set());
    }
    this.listeners.get(event)!.add(listener);
    return () => this.listeners.get(event)?.delete(listener);
  }

  emit<K extends keyof Events>(event: K, payload: Events[K]): void {
    this.listeners.get(event)?.forEach((fn) => fn(payload));
  }

  off<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): void {
    this.listeners.get(event)?.delete(listener);
  }
}

const emitter = new EventEmitter<EventMap>();
emitter.on('click', ({ x, y }) => console.log(x, y));
emitter.emit('click', { x: 100, y: 200 });

2. 异步事件

class AsyncEventEmitter<Events extends Record<string, any>> {
  private listeners = new Map<keyof Events, Set<Function>>();

  async emit<K extends keyof Events>(event: K, payload: Events[K]): Promise<void> {
    const fns = this.listeners.get(event);
    if (fns) await Promise.all([...fns].map((fn) => fn(payload)));
  }
}

3. 类型安全的事件构建器

type EventBuilder = {
  [K in string]: any;
};

function defineEvents<E extends EventBuilder>() {
  return {
    createEmitter: () => new EventEmitter<E>(),
    on: <K extends keyof E & string>(
      emitter: EventEmitter<E>,
      event: K,
      listener: (payload: E[K]) => void
    ) => emitter.on(event, listener),
  };
}

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式