typescript / intermediate
Snippet
Entwicklung einer typsicheren Event-Bus-Architektur
Ein Event-Bus entkoppelt Sender und Empfänger in modular aufgebauten Softwarearchitekturen. Durch gemappte Typen und indizierten Zugriff (`Events[K]`) garantiert TypeScript exakte Nutzlast-Typen für jedes Event.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
type EventMap = Record<string, unknown>;type EventCallback<T> = (data: T) => void;class TypedEventBus<Events extends EventMap> {private listeners: { [K in keyof Events]?: EventCallback<Events[K]>[] } = {};on<K extends keyof Events>(event: K, callback: EventCallback<Events[K]>): void {if (!this.listeners[event]) {this.listeners[event] = [];}this.listeners[event]!.push(callback);}emit<K extends keyof Events>(event: K, data: Events[K]): void {const callbacks = this.listeners[event];if (callbacks) {callbacks.forEach((cb) => cb(data));}}}interface AppEvents {userLoggedIn: { userId: string; timestamp: number };systemError: { code: number; message: string };}const bus = new TypedEventBus<AppEvents>();bus.on("userLoggedIn", (data) => console.log(`User ${data.userId} logged in`));bus.emit("userLoggedIn", { userId: "usr_101", timestamp: Date.now() });
Erklärung
1
type EventMap = Record<string, unknown>;
Einschränkung, die sicherstellt, dass Event-Namen zu entsprechenden Datenstrukturen zugewiesen werden.
2
private listeners: { [K in keyof Events]?: EventCallback<Events[K]>[] }
Verwendet Mapped Types, um jedem Event-Namen exakt passende Callback-Signaturen zuzuweisen.
3
on<K extends keyof Events>(event: K, callback: EventCallback<Events[K]>): void
Registriert einen Callback, der strikt auf die Nutzlast des angegebenen Events beschränkt ist.
4
emit<K extends keyof Events>(event: K, data: Events[K]): void
Löst Registrierungen aus und überprüft zur Kompilierzeit die Korrektheit aller übergebenen Parameter.