类型安全的发布订阅
00:00
构建类型安全的发布订阅模式
1. 类型定义
type EventMap = {
'user:login': { userId: string; timestamp: Date };
'user:logout': { userId: string };
'cart:add': { productId: string; quantity: number };
'cart:remove': { productId: string };
'order:create': { orderId: string; total: number };
};
type EventKey = keyof EventMap;
type EventHandler<K extends EventKey> = (payload: EventMap[K]) => void;
2. 实现
class PubSub<Events extends Record<string, any>> {
private subscribers = new Map<keyof Events, Set<Function>>();
subscribe<K extends keyof Events & string>(
event: K,
handler: (payload: Events[K]) => void
): () => void {
if (!this.subscribers.has(event)) {
this.subscribers.set(event, new Set());
}
this.subscribers.get(event)!.add(handler);
return () => this.subscribers.get(event)?.delete(handler);
}
publish<K extends keyof Events & string>(event: K, payload: Events[K]): void {
this.subscribers.get(event)?.forEach((fn) => fn(payload));
}
once<K extends keyof Events & string>(
event: K,
handler: (payload: Events[K]) => void
): () => void {
const unsubscribe = this.subscribe(event, (payload) => {
handler(payload);
unsubscribe();
});
return unsubscribe;
}
}
const bus = new PubSub<EventMap>();
bus.subscribe('user:login', ({ userId }) => console.log(userId));
bus.publish('user:login', { userId: '123', timestamp: new Date() });