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

TypeScript:如何根据属性从联合类型中条件提取类型?

根据Message类型收窄Payload类型的实现方案

要实现通过message.type字符串类型推断对应payload类型,你可以借助TypeScript的条件类型和Extract工具类型完成,同时需要将listener定义为泛型函数,让type参数和回调的payload类型形成关联。

步骤1:定义用于推断Payload的泛型类型

先创建一个泛型类型InferMessagePayloadByType,它接收一个type类型参数,从AnyMessage联合类型中筛选出匹配该type的成员,再提取其payload类型:

type Message1 = { type: 'message1', payload: string }
type Message2 = { type: 'message2', payload: boolean }

type AnyMessage = Message1 | Message2;
type AnyMessageType = AnyMessage['type']

// 核心类型:根据type推断对应的payload类型
type InferMessagePayloadByType<T extends AnyMessageType> = 
  Extract<AnyMessage, { type: T }>['payload']

这里Extract<UnionType, ConditionalType>的作用是从联合类型UnionType中提取出符合ConditionalType条件的成员,之后通过['payload']获取该成员的payload类型。

步骤2:改造listener为泛型函数

将listener定义为泛型函数,让type参数的类型和回调的payload类型绑定,这样TypeScript就能自动根据传入的type推断出payload的正确类型:

const listener = <T extends AnyMessageType>(
  type: T, 
  callback: (payload: InferMessagePayloadByType<T>) => any
) => {
  // 业务逻辑示例:比如模拟触发回调
  if (type === 'message1') {
    callback('hello' as InferMessagePayloadByType<T>);
  } else {
    callback(true as InferMessagePayloadByType<T>);
  }
}

使用示例

调用listener时,TypeScript会根据传入的type自动推断payload的类型,提供类型校验和提示:

// 传入'message1',payload自动推断为string类型
listener('message1', (payload) => {
  console.log(payload.toUpperCase()); // 类型合法,无报错
});

// 传入'message2',payload自动推断为boolean类型
listener('message2', (payload) => {
  console.log(payload ? '激活' : '关闭'); // 类型合法,无报错
});

// 如果传入错误的payload类型,TypeScript会直接报错
listener('message1', (payload) => {
  console.log(payload + 1); // 报错:string不能和number相加
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:05:23