emit e on com Segurança de Tipos
Garanta os dados associados corretos ao emitir eventos e escutá-los.
emit e on com Segurança de Tipos é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 4 aulas no total.
Uma assinatura de emit com segurança de tipos
Torne emit genérico em relação ao nome do evento K. O parâmetro de carga útil passa a ser Events[K], portanto o nome e a carga útil precisam corresponder.
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" });A carga útil incorreta é um erro de compilação
Se a carga útil não corresponder ao nome do evento, TypeScript a rejeitará. O genérico associa os dois 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");Nomes de eventos desconhecidos são rejeitados
Como K extends keyof Events, você não pode emitir um evento que não esteja no 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");Manipuladores tipados com on
O método on registra um manipulador cujo argumento é exatamente Events[K], para que os manipuladores recebam cargas úteis tipadas corretamente.
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));O argumento do manipulador é inferido
Você não anota o parâmetro do manipulador; TypeScript o infere a partir do nome do evento, oferecendo preenchimento automático completo dentro do corpo do manipulador.
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());
});Tratando eventos sem carga útil
Para eventos void, o manipulador simplesmente não recebe nenhum argumento útil. Você pode chamar o manipulador sem dados.
interface Events { logout: void }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("logout", () => console.log("logged out"));Combinando emit e on
Juntos, emit e on formam um sistema de publicação/assinatura tipado. Emitir um evento entrega uma carga útil corretamente tipada aos seus manipuladores.
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 });Restringindo a posição da carga útil
O genérico garante que o argumento de carga útil seja verificado em relação ao evento escolhido, detectando incompatibilidades no local da chamada, e não no interior de um manipulador.
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");Preenchimento automático para nomes de eventos
Como o primeiro parâmetro é keyof Events, os editores sugerem automaticamente nomes de eventos válidos enquanto você digita a chamada.
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 que os genéricos são essenciais aqui
Sem um genérico, você precisaria de sobrecargas para cada evento. Uma única assinatura genérica se adapta automaticamente a qualquer quantidade 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" }));Um padrão reutilizável
O padrão emit<K>(event, payload) e on<K>(event, handler) é o núcleo de todo emissor com segurança de tipos, que encapsularemos em uma classe a seguir.
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ção rápida: emit e on tipados
Teste sua compreensão sobre emit e on com segurança de tipos.
Recapitulação: emit e on com segurança de tipos
Você criou assinaturas genéricas de emit e on em que a carga útil é Events[K], portanto os nomes de eventos têm preenchimento automático, cargas úteis incorretas geram erros de compilação e os argumentos dos manipuladores são inferidos.
interface Events { login: { userId: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
console.log(emit("login", { userId: "u1" }));Aprenda TypeScript com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 101
- Aulas
- 352
Perguntas Frequentes
A aula “emit e on com Segurança de Tipos” é grátis?
Sim — o texto completo de “emit e on com Segurança de Tipos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 4 aulas no total.
O que vou aprender em “emit e on com Segurança de Tipos”?
Garanta os dados associados corretos ao emitir eventos e escutá-los. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar TypeScript Academy?
Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “emit e on com Segurança de Tipos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de TypeScript Academy?
Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Definindo Tipos de Mapas de Eventos
- emit e on com Segurança de Tipos
- Classe Genérica de Emissão de Eventos
- Inferindo Argumentos de Ouvintes