You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:57:19