0Pricing
TypeScript Academy · Lezione

emit e on type-safe

Imponi i payload corretti durante l’emissione e l’ascolto degli eventi.

emit e on type-safe è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 4 lezioni in totale.

Una firma emit tipizzata

Renda emit generico rispetto al nome dell'evento K. Il parametro del payload diventa quindi Events[K], perciò nome e payload devono corrispondere.

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 errato genera un errore di compilazione

Se il payload non corrisponde al nome dell'evento, TypeScript lo rifiuta. Il generico collega i due parametri.

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");

I nomi di eventi sconosciuti vengono rifiutati

Poiché K extends keyof Events, non può emettere un evento che non è presente nella mappa.

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");

Handler tipizzati con on

Il metodo on registra un handler il cui argomento è esattamente Events[K], quindi gli handler ricevono payload tipizzati correttamente.

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));

L'argomento dell'handler viene inferito

Non annoti il parametro dell'handler: TypeScript lo deduce dal nome dell'evento, offrendo il completamento automatico completo all'interno del corpo dell'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());
});

Gestire gli eventi senza payload

Per gli eventi void, l'handler non richiede alcun argomento utile. Può chiamare il relativo handler senza dati.

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

Combinare emit e on

Insieme, emit e on formano un sistema pub/sub tipizzato. L'emissione di un evento consegna un payload tipizzato correttamente ai relativi handler.

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 });

Vincolare la posizione del payload

Il generico garantisce che l'argomento del payload venga verificato rispetto all'evento selezionato, rilevando le incompatibilità nel punto della chiamata e non in profondità all'interno di 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");

Completamento automatico per i nomi degli eventi

Poiché il primo parametro è keyof Events, gli editor completano automaticamente i nomi degli eventi validi mentre si digita la chiamata.

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");

Perché i generici sono essenziali in questo caso

Senza un generico, sarebbero necessari overload per ogni evento. Una singola firma generica si adatta automaticamente a qualsiasi numero di eventi.

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 pattern riutilizzabile

Questo pattern emit<K>(event, payload) e on<K>(event, handler) è il nucleo di ogni emitter tipizzato, che nel prossimo passaggio incapsuleremo in una classe.

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));

Verifica rapida: emit e on tipizzati

Verifichi la Sua comprensione di emit e on tipizzati.

Riepilogo: emit e on tipizzati

Ha creato firme generiche per emit e on in cui il payload è Events[K], quindi i nomi degli eventi vengono completati automaticamente, i payload errati generano errori di compilazione e gli argomenti degli handler vengono inferiti.

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

Domande Frequenti

La lezione «emit e on type-safe» è gratuita?

Sì — il testo completo di «emit e on type-safe» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 4 lezioni in totale.

Cosa imparerò in «emit e on type-safe»?

Imponi i payload corretti durante l’emissione e l’ascolto degli eventi. Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare TypeScript Academy?

Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «emit e on type-safe»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?

Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Tipizzare le mappe degli eventi
  2. emit e on type-safe
  3. Classe Generic Event Emitter
  4. Inferire gli argomenti dei listener
← Torna a TypeScript Academy