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

如何使用条件类型实现EventClientEvent的event与payload类型关联

解决TypeScript事件类型关联问题

要实现event字段和payload类型的严格绑定,最简洁的方案是使用可辨识联合类型(Discriminated Union),通过类型映射表关联事件名与对应payload类型,让TypeScript自动根据event的值推断payload的具体类型。

步骤1:定义事件-Payload类型映射表

先创建映射类型,把每个事件名和对应的payload类型(按需求包装为数组)绑定:

type TransactionRowTypes = {
    // transaction row types
    id: string;
    amount: number;
};
type UserDataTypes = {
    // user data types
    userId: number;
    username: string;
};
type InventoryRowTypes = {
    // inventory row types
    itemId: string;
    stock: number;
};

// 核心映射表:事件名 → 对应payload类型
type EventPayloadMap = {
  transactions: TransactionRowTypes[];
  userchange: UserDataTypes[];
  inventory: InventoryRowTypes[];
};

步骤2:生成可辨识联合类型

基于映射表,将公共字段time与每个事件的专属字段合并,生成最终的EventClientEvent类型:

type EventClientEvent = {
  time: number;
} & {
  // 遍历映射表所有键,生成每个事件的专属类型
  [K in keyof EventPayloadMap]: {
    event: K;
    payload: EventPayloadMap[K];
  };
}[keyof EventPayloadMap];

效果验证

使用该类型时,TypeScript会自动根据event的值推断payload类型:

function processEvent(event: EventClientEvent) {
  switch (event.event) {
    case 'transactions':
      // payload自动推断为TransactionRowTypes[]
      event.payload.forEach(tx => console.log(tx.amount));
      break;
    case 'userchange':
      // payload自动推断为UserDataTypes[]
      console.log(event.payload[0].username);
      break;
    case 'inventory':
      // payload自动推断为InventoryRowTypes[]
      console.log(event.payload[0].stock);
      break;
  }
}

关于你写的EventName类型

你定义的EventName<T>可用于提取单个事件类型的事件名字面量,但在当前方案中,直接从映射表提取所有事件名的联合类型更简洁:

// 等价于 'transactions' | 'userchange' | 'inventory'
type EventName = keyof EventPayloadMap;

扩展性说明

后续新增事件时,只需在EventPayloadMap中添加新的键值对,EventClientEvent会自动包含新事件类型,无需修改其他代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:30:58