Saltar al contenido
Tipar un emisor de eventos

    ↑↓ mover · ⏎ abrir · esc cerrar

    Patrones

    ¿Cómo mantengo cada nombre de evento emparejado con su carga y listener correctos?

    Usa un mapa de eventos y un parámetro de clave para que el nombre seleccione la carga en ambos métodos.

    La receta

    type Handler<Events, K extends keyof Events> =
      (payload: Events[K]) => void
    
    type TypedEmitter<Events extends object> = {
      on<K extends keyof Events>(event: K, handler: Handler<Events, K>): void
      emit<K extends keyof Events>(event: K, payload: Events[K]): void
    }
    
    type Events = {
      saved: { id: string }
      failed: { message: string }
    }
    
    declare const bus: TypedEmitter<Events>
    
    bus.on('saved', payload => payload.id)
    bus.emit('failed', { message: 'offline' })

    La compilación compila esto y comprueba cada resultado de abajo.

    Cómo funciona

    1. 01
      K extends keyof Events

      La clave solo puede ser un nombre de evento declarado.

    2. 02
      payload: Events[K]

      El acceso indexado convierte el nombre elegido en su carga exacta.

    Lo que obtienes

    Dónde falla

    El tipo solo protege llamadas que pasan por esta interfaz. Un emisor débilmente tipado por debajo aún puede entregar datos inválidos, así que valida eventos que crucen procesos o redes.

    Conclusión

    Un mapa más `K extends keyof Map` es la forma estándar de correlacionar un nombre con sus datos.

    Véase también

    Patrones