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

泛型函数中联合类型的keyof安全类型标注问题

问题解析:为什么keyof T没解析成'name' | 'fleas'?

先看你的代码:

type MyAnimals = { name: "dog", fleas: 2 } | { name: "cat" }
function GetKeys<T extends MyAnimals>(animal: T) {
  for (let k in animal) {
    const keyAsKeyOf = k as keyof T;
          // ^? const keyAsKey: keyof T
          // 为什么不是`name`?
  }
}

核心原因:TypeScript中keyof对联合类型的处理逻辑

当keyof作用于联合类型时,它不会取所有成员键的并集,而是取所有成员的共有键的交集。

你的T是MyAnimals的子类型,而MyAnimals是两个对象类型的联合:

  • 第一个成员的键是'name' | 'fleas'
  • 第二个成员的键是'name'

两者的共有键只有'name',所以TypeScript在泛型函数的上下文里,会把keyof T推断为这个共有键'name'——因为泛型T可以是联合类型中的任意一个成员,TypeScript必须保证类型安全,只能取所有可能情况都存在的键。

如果想提取联合类型所有成员的键的并集,可以用分布式条件类型实现:

type AllKeys<T> = T extends unknown ? keyof T : never;
type AnimalKeys = AllKeys<MyAnimals>; // 得到 'name' | 'fleas'

但回到你的循环场景:for...in遍历的是当前传入对象的实际键,但因为T是泛型,TypeScript编译期无法确定它具体指向联合中的哪一个成员,所以只能用共有键做类型推断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:54:29