TypeScript Academy · Lección

emit y on con seguridad de tipos

Imponga los payloads correctos al emitir eventos y escuchar eventos.

Lección 2 de 413 pasos

emit y on con seguridad de tipos es una lección gratuita de TypeScript Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de TypeScript Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de TypeScript Academy incluye 4 lecciones en total.

Una firma de emit con seguridad de tipos

Haga que emit sea genérico respecto al nombre de evento K. El parámetro de payload será entonces Events[K], por lo que el nombre y el payload deben coincidir.

interface Events { login: { userId: string }; logout: void }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {
  console.log("emit", event, JSON.stringify(payload));
}
emit("login", { userId: "u1" });

Un payload incorrecto es un error de compilación

Si el payload no coincide con el nombre del evento, TypeScript lo rechaza. El genérico vincula ambos parámetros.

interface Events { login: { userId: string } }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {}
// emit("login", { id: "u1" }); // Error: id is not userId
emit("login", { userId: "u1" });
console.log("ok");

Los nombres de evento desconocidos se rechazan

Como K extends keyof Events, no puede emitir un evento que no esté en el mapa.

interface Events { login: { userId: string } }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {}
// emit("signup", { userId: "x" }); // Error: "signup" not a key
emit("login", { userId: "x" });
console.log("only known events");

Handlers tipados con on

El método on registra un handler cuyo argumento es exactamente Events[K], de modo que los handlers reciben payloads correctamente tipados.

interface Events { login: { userId: string }; logout: void }
function on<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void) {
  console.log("subscribed to", event);
}
on("login", (p) => console.log(p.userId));

El argumento del handler se infiere

No anote el parámetro del handler; TypeScript lo infiere a partir del nombre del evento y proporciona autocompletado completo dentro del cuerpo del handler.

interface Events { message: { text: string } }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("message", (p) => {
  // p is { text: string }
  console.log(p.text.toUpperCase());
});

Gestionar eventos sin payload

En los eventos void, el handler simplemente no recibe ningún argumento útil. Puede llamar a su handler sin datos.

interface Events { logout: void }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("logout", () => console.log("logged out"));

Combinar emit y on

Juntos, emit y on forman un sistema pub/sub tipado. Emitir un evento entrega un payload correctamente tipado a sus handlers.

interface Events { ping: { at: number } }
type Handler<K extends keyof Events> = (p: Events[K]) => void;
const handlers: { ping: Handler<"ping">[] } = { ping: [] };
function on<K extends keyof Events>(e: K, h: Handler<K>) { handlers[e].push(h as Handler<"ping">); }
function emit<K extends keyof Events>(e: K, p: Events[K]) { handlers[e].forEach(h => h(p as Events["ping"])); }
on("ping", p => console.log("at", p.at));
emit("ping", { at: 5 });

Restringir la posición del payload

El genérico garantiza que el argumento de payload se compruebe con respecto al evento elegido, detectando las incompatibilidades en el sitio de llamada, no dentro de un handler.

interface Events { add: { x: number; y: number } }
function emit<K extends keyof Events>(e: K, p: Events[K]) {
  return e;
}
emit("add", { x: 1, y: 2 });
// emit("add", { x: 1 }); // Error: y missing
console.log("payload checked");

Autocompletado para nombres de eventos

Como el primer parámetro es keyof Events, los editores completan automáticamente los nombres de evento válidos mientras escribe la llamada.

interface Events { open: void; close: void }
function emit<K extends keyof Events>(e: K, p: Events[K]) {}
// Typing emit(" suggests "open" and "close"
emit("open", undefined as void);
console.log("autocompleted names");

Por qué los genéricos son esenciales aquí

Sin un genérico, necesitaría sobrecargas para cada evento. Una única firma genérica se adapta automáticamente a cualquier número de eventos.

interface Events { a: { x: number }; b: { y: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return p; }
console.log(emit("a", { x: 1 }), emit("b", { y: "hi" }));

Un patrón reutilizable

Este patrón emit<K>(event, payload) y on<K>(event, handler) es la base de todo emisor con seguridad de tipos, que convertiremos en una clase a continuación.

interface Events { tick: { n: number } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
function on<K extends keyof Events>(e: K, h: (p: Events[K]) => void) { return e; }
console.log(emit("tick", { n: 1 }), on("tick", p => p.n));

Comprobación rápida: emit y on tipados

Compruebe su comprensión de emit y on con seguridad de tipos.

Resumen: emit y on con seguridad de tipos

Creó firmas genéricas para emit y on en las que el payload es Events[K], por lo que los nombres de eventos se autocompletan, los payloads incorrectos producen errores de compilación y los argumentos de los handlers se infieren.

interface Events { login: { userId: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
console.log(emit("login", { userId: "u1" }));
Gratis para empezar

Aprende TypeScript con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
101
Lecciones
352

Preguntas frecuentes

¿La lección «emit y on con seguridad de tipos» es gratis?

Sí — el texto completo de «emit y on con seguridad de tipos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de TypeScript Academy, actualiza a CoddyKit PRO. El curso de TypeScript Academy incluye 4 lecciones en total.

¿Qué aprenderé en «emit y on con seguridad de tipos»?

Imponga los payloads correctos al emitir eventos y escuchar eventos. Practicas TypeScript Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar TypeScript Academy?

No se requiere experiencia previa. TypeScript Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «emit y on con seguridad de tipos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de TypeScript Academy?

Sí. Cada lección de TypeScript Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Tipado de mapas de eventos
  2. emit y on con seguridad de tipos
  3. Clase de emisor de eventos genérica
  4. Inferencia de argumentos de listeners
← Volver a TypeScript Academy