Typowany EventEmitter
Klasa Emitter<Events> dostaje opis zdarzeń: new Emitter<{ login: { userId: number }; message: string }>(). Metoda on(event, handler) subskrybuje handler i zwraca funkcję wypisania, emit(event, payload) wywołuje handlery tego zdarzenia.
Zrób typy dokładnymi: nazwa zdarzenia to tylko jeden z kluczy Events, a typ payload w handlerze i w emit pochodzi z opisu właśnie tego zdarzenia.
Ctrl+Enter uruchamia testy. Tab robi wcięcie; aby wyjść z edytora klawiaturą, naciśnij Esc, a potem Tab. Kod zapisuje się w tej przeglądarce.
Testy (7)
Testy typów sprawdza kompilator TypeScriptu w trybie strict. Expect<Equal<A, B>> przechodzi, gdy typy są dokładnie takie same, a // @ts-expect-error, gdy następna linia się nie kompiluje. Pierwsze uruchomienie pobiera kompilator, więc trwa kilka sekund.
- typy
type E = { login: { userId: number }; message: string }; const e = new Emitter<E>(); e.on('login', (payload) => { type _ = Expect<Equal<typeof payload, { userId: number }>>; });
- typy
type E = { login: { userId: number }; message: string }; const e = new Emitter<E>(); // @ts-expect-error - message carries a string e.emit('message', 42);
- typy
type E = { login: { userId: number }; message: string }; const e = new Emitter<E>(); // @ts-expect-error - there is no such event e.on('signup', () => {});
const e = new Emitter(); const a = fn(); const b = fn(); e.on('message', a); e.on('message', b); e.emit('message', 'hi'); expect(a).toHaveBeenCalledWith('hi'); expect(b).toHaveBeenCalledWith('hi');
const e = new Emitter(); const h = fn(); const off = e.on('login', h); e.emit('login', { userId: 1 }); off(); e.emit('login', { userId: 2 }); expect(h).toHaveBeenCalledTimes(1); expect(h).toHaveBeenLastCalledWith({ userId: 1 });
const e = new Emitter(); expect(() => e.emit('nobody-listens', 1)).not.toThrow();
const e = new Emitter(); const a = fn(); const b = fn(); e.on('x', a); e.on('y', b); e.emit('x', 1); expect(a).toHaveBeenCalledTimes(1); expect(b).toHaveBeenCalledTimes(0);