typestar

Un emisor de eventos tipado en TypeScript

Un mapa de nombres de evento a payloads vuelve seguros on y emit.

type EventMap = {
  run: { lang: string; tpm: number };
  cleared: { set: string };
  error: Error;
};

class Emitter<Events extends Record<string, unknown>> {
  #handlers = new Map<keyof Events, Set<(payload: never) => void>>();

  on<K extends keyof Events>(type: K, handler: (payload: Events[K]) => void) {
    const set = this.#handlers.get(type) ?? new Set();
    set.add(handler as (payload: never) => void);
    this.#handlers.set(type, set);
    return () => set.delete(handler as (payload: never) => void);
  }

  emit<K extends keyof Events>(type: K, payload: Events[K]): number {
    const set = this.#handlers.get(type);
    set?.forEach((handler) => (handler as (p: Events[K]) => void)(payload));
    return set?.size ?? 0;
  }
}

const bus = new Emitter<EventMap>();
bus.on("run", ({ tpm }) => console.log("tpm", tpm));
console.log(bus.emit("run", { lang: "ts", tpm: 98 }));
// bus.emit("run", { lang: "ts" }); // error: falta tpm

Cómo funciona

  1. El mapa de eventos es la única fuente de verdad.
  2. K extends keyof Events ata el payload al nombre.
  3. Un payload equivocado, o un evento desconocido, no compila.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
27
Caracteres a escribir
900
Tokens
280
Ritmo de tres estrellas
110 tpm

Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 153 segundos.

Escribe este fragmento

Paso 1 de 2 en Eventos tipados; paso 3 de 8 en Async y módulos.

← Anterior Siguiente →