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

如何基于嵌套类型的label筛选TypeScript对象的键类型

如何根据label筛选Payloads的键类型?

已知类型定义

type Payloads = {
    EventA: { label: 'Foo', content: object }
    EventB: { label: 'Bar', content: object }
    EventC: { label: 'Baz', content: object }
}

type SelectLabels = 'Foo' | 'Bar'

需求

需要创建类型TypeGoesHere,仅包含Payloads中值类型的label属于SelectLabels的键,使得调用函数时:

function f(x: TypeGoesHere) {}
f('EventA') // 合法
f('EventB') // 合法
f('EventC') // 报错

尝试的错误代码及问题

尝试了以下代码:

type TypeGoesHere = Pick<keyof Payloads, Payloads[keyof Payloads]['label'][SelectLabels]>

但出现错误:

Property 'Bar' does not exist on type '"Foo" | "Bar" | "Baz"'.ts(2339)
Property 'Foo' does not exist on type '"Foo" | "Bar" | "Baz"'.ts(2339)

正确实现方法

要实现这个需求,需要利用TypeScript的映射类型和条件类型筛选符合条件的键,以下是两种可行写法:

写法一:条件类型映射筛选

type TypeGoesHere = {
  [K in keyof Payloads]: Payloads[K]['label'] extends SelectLabels ? K : never
}[keyof Payloads]

写法二:结合Extract工具类型

type TypeGoesHere = Extract<keyof Payloads, {
  [K in keyof Payloads]: Payloads[K]['label'] extends SelectLabels ? K : never
}[keyof Payloads]>

原理说明

  • 写法一中,先遍历Payloads的所有键K,判断对应值的label是否属于SelectLabels:符合条件则保留键K,否则设为never。最后通过[keyof Payloads]索引访问,自动过滤掉never类型,得到目标联合类型"EventA" | "EventB"。
  • 写法二则借助Extract工具类型,从keyof Payloads中提取出符合条件的键,效果和写法一完全一致。

验证效果:

function f(x: TypeGoesHere) {}
f('EventA') // ✅ 合法
f('EventB') // ✅ 合法
f('EventC') // ❌ 报错:类型'"EventC"'的参数不能赋给类型'"EventA" | "EventB"'的参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:28:14