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

如何创建动态类型替代函数双参数并提取预定义回调类型?

解决方案

要实现根据事件名自动推导回调参数类型的on函数,核心是建立事件名与对应参数类型的映射关系,再通过TypeScript的泛型或联合类型实现类型关联。以下是两种可行方案:

方案1:双参数泛型版(保留原函数结构)

先定义事件与参数类型的映射接口,再通过泛型让TypeScript自动根据事件名推断回调类型:

// 定义Entry类型(根据业务需求补充)
interface Entry {
  id: string;
  // 其他字段...
}

// 建立事件名→参数类型的映射
type EventMap = {
  loaded: Entry[];
  changed: number;
};

// 提取事件名字面量类型
type EventName = keyof EventMap;

// 泛型版on函数,自动推断回调参数类型
const on = <E extends EventName>(eventName: E, callback: (data: EventMap[E]) => void) => {
  // 这里写事件绑定逻辑,比如:
  // emitter.on(eventName, callback);
};

// 使用示例——无需手动指定类型,自动推断
on('loaded', (list) => {
  // list类型自动为Entry[]
  console.log('加载完成,共', list.length, '条数据');
});

on('changed', (index) => {
  // index类型自动为number
  console.log('第', index + 1, '条数据发生变更');
});

方案2:单参数联合类型版(对应你想要的DynamicParams形式)

如果想把两个参数合并为一个动态参数对象,可以定义联合类型来实现:

// 复用之前的Entry、EventMap、EventName定义
interface Entry { /* ... */ }
type EventMap = { loaded: Entry[]; changed: number };
type EventName = keyof EventMap;

// 定义DynamicParams联合类型,每个成员对应一个事件的参数组合
type DynamicParams = {
  [E in EventName]: {
    eventName: E;
    callback: (data: EventMap[E]) => void;
  };
}[EventName];

// 使用DynamicParams的on函数
const on = (params: DynamicParams) => {
  // 事件绑定逻辑示例:
  // emitter.on(params.eventName, params.callback);
};

// 使用示例
on({
  eventName: 'loaded',
  callback: (list) => { /* list自动为Entry[] */ }
});

on({
  eventName: 'changed',
  callback: (index) => { /* index自动为number */ }
});

进阶:从事件数组动态生成映射

如果你的事件列表是预先定义的数组,也可以通过as const保留字面量类型,动态生成映射:

interface Entry { /* ... */ }

// 用as const让TypeScript保留每个事件的字面量类型
const eventDefinitions = [
  { name: 'loaded', paramType: [] as Entry[] },
  { name: 'changed', paramType: 0 as number }
] as const;

// 提取事件名字面量类型
type EventName = typeof eventDefinitions[number]['name'];

// 动态生成EventMap
type EventMap = {
  [E in typeof eventDefinitions[number] as E['name']]: E['paramType'];
};

// 后续的on函数实现和前面两种方案一致

关键说明

  • 避免用any的核心是明确事件名与参数类型的绑定关系,TypeScript才能基于这个映射做类型推断。
  • 你之前尝试的数组形式事件定义,需要用as const强制TypeScript保留字面量值类型,否则无法提取具体的事件名字符串(只会得到string类型)。

内容的提问来源于stack exchange,提问作者WichyCake

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:40:38