// 事件类型定义(使用元组类型)
interface UploaderEventMap {
[key: string]: any[]; // 索引签名
"taskAdd": [tasks: UTask[]];
"taskComplete": [task: UTask];
"taskError": [error: UErrorEvent, retry: () => void];
"taskCancel": [task: UTask, reason: string];
"taskProgress": [progress: UProgressEvent];
}
class EventEmitter<T extends Record<string, any[]>> {
private callbacks = new Map<keyof T, Array<(...args: any[]) => void>>();
// 类型安全的事件监听方法
on<K extends keyof T>(
eventName: K,
callback: (...args: T[K]) => void
): this {
const existing = this.callbacks.get(eventName) || [];
existing.push(callback);
this.callbacks.set(eventName, existing);
return this;
}
// 改进后的emit方法(支持多参数)
emit<K extends keyof T>(eventName: K, ...args: T[K]): this {
const callbacks = this.callbacks.get(eventName);
if (callbacks) {
callbacks.forEach(callback => {
callback(...args);
});
}
return this;
}
}
// 使用示例
const uploader = new EventEmitter<UploaderEventMap>();
// 注册事件监听(自动推断参数类型)
uploader.on("taskError", (error, retry) => {
console.error(error.message);
retry();
});
// 触发事件(类型安全检查)
uploader.emit("taskError",
{ error: new Error("Upload failed"), task: {} as UTask },
() => console.log("Retrying...")
);
// 类型错误示例(TS会报错)
uploader.emit("taskProgress"); // ❌ 缺少参数
uploader.emit("taskCancel", {} as UTask); // ❌ 缺少第二个参数
进阶优化方案:
1. 异步事件支持
class AsyncEventEmitter<T extends Record<string, any[]>> {
async emitAsync<K extends keyof T>(
eventName: K,
...args: T[K]
): Promise<void> {
const callbacks = this.callbacks.get(eventName) || [];
await Promise.all(callbacks.map(cb => cb(...args)));
}
}
// 使用示例
await uploader.emitAsync("beforeUpload", task);
2. 优先级控制
interface CallbackWithPriority {
priority: number;
callback: (...args: any[]) => void;
}
class PriorityEventEmitter<T extends Record<string, any[]>> {
private callbacks = new Map<keyof T, CallbackWithPriority[]>();
on<K extends keyof T>(
eventName: K,
callback: (...args: T[K]) => void,
priority = 0
): this {
const existing = this.callbacks.get(eventName) || [];
existing.push({ priority, callback });
existing.sort((a, b) => b.priority - a.priority);
this.callbacks.set(eventName, existing);
return this;
}
}
3. 一次事件监听
once<K extends keyof T>(
eventName: K,
callback: (...args: T[K]) => void
): this {
const wrapper = (...args: T[K]) => {
callback(...args);
this.off(eventName, wrapper);
};
return this.on(eventName, wrapper);
}
类型安全验证机制:
-
参数数量校验:
uploader.emit("taskCancel", task); // ❌ 缺少第二个参数 -
参数类型校验:
uploader.emit("taskError", "error string", () => {}); // ❌ 第一个参数类型错误 -
事件名称校验:
uploader.on("unknownEvent", () => {}); // ❌ 未知事件类型
该方案通过 TypeScript 的类型系统实现了:
- 动态参数数量支持
- 严格的参数类型检查
- 自动类型推断
- 可扩展的事件架构
适用于需要处理复杂事件参数的场景,如文件上传管理器、游戏事件系统等,确保在开发阶段即可捕获参数类型错误。
内容为AI生成