TypeScript如何在函数签名内引用指定函数参数?
实现类型安全的事件管理器
核心思路是用泛型类型映射关联事件名与对应的回调函数类型,让fireEvent能根据传入的事件名自动推导所需参数的类型。
步骤1:定义事件类型映射
先声明一个类型,明确所有事件名及其对应的回调函数签名:
type EventMap = { userLogin: (username: string, timestamp: number) => void; messageReceived: (content: string, senderId: number) => void; logout: () => void; };
步骤2:实现类型安全的EventManager类
利用TypeScript泛型和Parameters工具类型,让fireEvent方法动态匹配事件对应的参数类型:
class EventManager<T extends Record<string, (...args: any[]) => void>> { private events: Partial<Record<keyof T, T[keyof T][]>> = {}; // 绑定事件回调 on<Name extends keyof T>(name: Name, callback: T[Name]) { if (!this.events[name]) { this.events[name] = []; } (this.events[name] as T[Name][]).push(callback); } // 触发事件:根据事件名自动推导参数类型 fireEvent<Name extends keyof T>(name: Name, ...args: Parameters<T[Name]>) { const callbacks = this.events[name]; callbacks?.forEach(callback => callback(...args)); } }
步骤3:使用示例
现在调用fireEvent时,TypeScript会自动给出参数提示,参数不匹配会直接报错:
const manager = new EventManager<EventMap>(); // 绑定回调 manager.on('userLogin', (username, time) => { console.log(`${username} logged in at ${time}`); }); // 正确调用:有类型提示,参数完全匹配 manager.fireEvent('userLogin', 'Alice', Date.now()); // 错误调用:TypeScript直接报错 manager.fireEvent('userLogin', 'Bob'); // 缺少timestamp参数 manager.fireEvent('messageReceived', 123, 'Charlie'); // 参数类型顺序颠倒
关键原理说明
EventMap为所有事件的回调签名提供了明确的类型契约,是类型检查的基础。fireEvent的泛型参数Name extends keyof T将事件名name与泛型Name绑定,TypeScript通过T[Name]拿到对应事件的回调类型,再用Parameters<T[Name]>提取回调的参数类型数组,最终实现参数的强类型约束。
内容的提问来源于stack exchange,提问作者cl10k
相关产品推荐
相关产品推荐

