TypeScript+React实现类Vue EventBus时spread参数报错解决
TypeScript 实现类型安全的Vue风格EventBus
错误根源
原代码的类型报错和ESLint问题来自两点:
- 初始定义的回调类型是无入参函数
() => void,和$emit时展开传参的行为类型不匹配 - 后续修改的
(params: Array<string | number>) => void要求回调必须接收单个数组入参,和展开传参的逻辑不符;如果回调内没有使用这个形参,自然会触发no-unused-vars规则。
可直接使用的实现代码
// 定义支持任意个入参的回调类型,使用剩余参数语法匹配展开传参 type EventCallback = (...args: Array<string | number | boolean | object | null | undefined>) => void class _EventBus { // 用Map存储事件回调,相比普通对象更适合频繁增删场景,避免原型链键名冲突 private readonly bus: Map<string | number, EventCallback> constructor() { this.bus = new Map() } /** * 解绑指定事件 * @param id 事件唯一标识 */ $off(id: string | number) { this.bus.delete(id) } /** * 注册事件监听 * @param id 事件唯一标识 * @param callback 事件触发时执行的回调 */ $on(id: string | number, callback: EventCallback) { this.bus.set(id, callback) } /** * 触发事件 * @param id 事件唯一标识 * @param args 传给回调的任意个参数 */ $emit(id: string | number, ...args: Parameters<EventCallback>) { const callback = this.bus.get(id) if (callback) { callback(...args) } } /** * 注册只触发一次的事件监听 * @param id 事件唯一标识 * @param callback 事件触发时执行的回调 */ $once(id: string | number, callback: EventCallback) { const onceWrapper: EventCallback = (...args) => { callback(...args) this.$off(id) } this.bus.set(id, onceWrapper) } } export const EventBus = new _EventBus()
关键说明
- 回调类型使用剩余参数语法定义,既匹配
$emit时的展开传参逻辑,也兼容任意参数个数的回调传入:不需要参数的回调可以直接写() => {},只需要部分参数的回调可以只声明用到的形参,不会触发no-unused-vars报错。 - 存储结构替换为
Map,相比普通对象在频繁增删键值对的场景性能更好,也不会出现对象原型属性导致的键名冲突问题。 $emit调整为剩余参数传参形式,调用方式和Vue原生EventBus完全一致,不需要手动把参数包成数组:// 调用示例 EventBus.$emit('user:login', 1001, '张三', { role: 'admin' })
React场景使用注意
事件监听必须在组件卸载时解绑,避免内存泄漏:
import { useEffect } from 'react' import { EventBus } from './event-bus' export default function UserPanel() { useEffect(() => { // 注册监听 const handleLogin = (userId: number, userName: string) => { console.log('用户登录:', userId, userName) } EventBus.$on('user:login', handleLogin) // 组件卸载时解绑 return () => { EventBus.$off('user:login') } }, []) return <div>用户面板</div> }
如果需要更严格的类型约束,可以基于泛型扩展事件名和参数的映射关系,实现事件名、参数类型的自动校验,避免传错参数。
内容的提问来源于stack exchange,提问作者tail
相关产品推荐
相关产品推荐

