Bezpieczne typowo emit i on
Wymuszaj poprawne dane podczas emitowania i nasłuchiwania zdarzeń
Bezpieczne typowo emit i on to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Bezpieczna typowo sygnatura emit
Należy uczynić emit generycznym względem nazwy zdarzenia K. Parametr payloadu będzie wtedy miał typ Events[K], więc nazwa i payload muszą do siebie pasować.
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" });Niepoprawny payload powoduje błąd kompilacji
Jeśli payload nie pasuje do nazwy zdarzenia, TypeScript go odrzuci. Typ generyczny wiąże ze sobą oba parametry.
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");Nieznane nazwy zdarzeń są odrzucane
Ponieważ K extends keyof Events, nie można emitować zdarzenia, którego nie ma w mapie.
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");Typowane handlery z użyciem on
Metoda on rejestruje handler, którego argument ma dokładnie typ Events[K], dzięki czemu handlery otrzymują poprawnie typowane payloady.
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));Typ argumentu handlera jest wywnioskowany
Nie trzeba opisywać typu parametru handlera — TypeScript wywnioskuje go z nazwy zdarzenia, zapewniając pełne autouzupełnianie wewnątrz ciała handlera.
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());
});Obsługa zdarzeń bez payloadu
W przypadku zdarzeń typu void handler po prostu nie przyjmuje użytecznego argumentu. Jego handler można wywołać bez danych.
interface Events { logout: void }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("logout", () => console.log("logged out"));Łączenie emit i on
Razem emit i on tworzą typowane rozwiązanie pub/sub. Emitowanie zdarzenia dostarcza jego handlerom poprawnie typowany payload.
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 });Ograniczanie pozycji payloadu
Typ generyczny gwarantuje, że argument payloadu jest sprawdzany względem wybranego zdarzenia, wykrywając niezgodności w miejscu wywołania, a nie głęboko w handlerze.
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");Autouzupełnianie nazw zdarzeń
Ponieważ pierwszy parametr ma typ keyof Events, edytory podpowiadają poprawne nazwy zdarzeń podczas wpisywania wywołania.
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");Dlaczego generyki są tutaj niezbędne
Bez typu generycznego trzeba byłoby utworzyć przeciążenie dla każdego zdarzenia. Jedna generyczna sygnatura automatycznie skaluje się do dowolnej liczby zdarzeń.
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" }));Wzorzec wielokrotnego użytku
Wzorzec emit<K>(event, payload) i on<K>(event, handler) stanowi podstawę każdego bezpiecznego typowo emitera, który w następnej kolejności zamkniemy w klasie.
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));Szybkie sprawdzenie: typowane emit i on
Proszę sprawdzić swoją wiedzę na temat bezpiecznych typowo metod emit i on.
Podsumowanie: bezpieczne typowo emit i on
Zbudowali Państwo generyczne sygnatury emit i on, w których payload ma typ Events[K], dzięki czemu nazwy zdarzeń są dostępne w autouzupełnianiu, niepoprawne payloady powodują błędy kompilacji, a argumenty handlerów są wywnioskowywane.
interface Events { login: { userId: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
console.log(emit("login", { userId: "u1" }));Ucz się TypeScript dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 101
- Lekcje
- 352
Często zadawane pytania
Czy lekcja „Bezpieczne typowo emit i on” jest bezpłatna?
Tak — pełny tekst „Bezpieczne typowo emit i on” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Bezpieczne typowo emit i on”?
Wymuszaj poprawne dane podczas emitowania i nasłuchiwania zdarzeń Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?
Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Bezpieczne typowo emit i on”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?
Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Typowanie map zdarzeń
- Bezpieczne typowo emit i on
- Generyczna klasa Event Emitter
- Wnioskowanie argumentów listenerów