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

TypeScript:从嵌套对象值生成新类型时无键报错,如何解决?

问题原因与解决方法

问题出在哪?

  1. AllValuesOf 类型逻辑错误:你写的 AllValuesOf<T> 尝试取 T[keyof T],但 Events 是数组类型,keyof T 包含了数组的所有键(比如 length、push 这些数组方法/属性),所以 T[keyof T] 拿到的不只是数组里的对象元素,还混进了数组本身的属性类型,完全偏离了你的需求。
  2. 联合类型存在无 name 属性的成员:就算你拿到了数组元素的联合类型({name: 'foo'} | {name: 'bar'} | {value: 'baz'}),直接访问 ['name'] 也会报错,因为联合类型里的 {value: 'baz'} 没有 name 属性,TypeScript 不允许访问联合类型中不存在的属性。

正确实现方式

要达到预期效果,需要分两步:

  1. 提取数组的元素类型(用 T[number],数组的数字索引对应的就是元素);
  2. 过滤出带有 name 属性的元素类型,再提取 name 的值类型。

修改后的代码:

const events = [
  { name: 'foo' },
  { name: 'bar' },
  { value: 'baz' }
] as const;

type Events = typeof events;

// 提取数组元素类型,再过滤出有name属性的类型,最后取name的值
type Name = Extract<Events[number], { name: unknown }>['name']; 
// 结果:"foo" | "bar"

或者用条件类型实现:

type NameFromArray<T extends readonly any[]> = 
  T[number] extends { name: infer N } ? N : never;

type Name = NameFromArray<Events>; // "foo" | "bar"

两种方式都能正确得到你想要的 'foo' | 'bar' 类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 15:47:05