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

TypeScript中getDeepValue泛型用extends与不用的差异及报错问题

关于TypeScript getDeepValue函数的类型问题解析

两种写法的核心差异

错误写法

export const getDeepValue = <T, >(obj: T, firstKey: keyof T, secondKey: keyof T[keyof T]) => { 
  return obj[firstKey][secondKey]; 
}; 

const obj = { 
  foo: { a: true, b: 2, }, 
  bar: { c: "12", d: 18, }, 
}; 

const value = getDeepValue(obj, "foo", "a"); // 报错:secondKey类型为never

正确写法

export const getDeepValue = <T, TFK extends keyof T, TSK extends keyof T[TFK]>(obj: T, firstKey: TFK, secondKey: TSK) => { 
  return obj[firstKey][secondKey]; 
}; 

const obj = { 
  foo: { a: true, b: 2, }, 
  bar: { c: "12", d: 18, }, 
}; 

const value = getDeepValue(obj, "foo", "a"); // 类型正常推导

两者的差异在于泛型的绑定逻辑:

  • 错误写法只声明了泛型T,secondKey的类型是所有子对象key的交集,而非对应firstKey的子对象key。
  • 正确写法额外声明了TFK(绑定传入的firstKey的具体类型)和TSK(绑定TFK对应子对象的key类型),让secondKey的类型和firstKey强关联,实现了类型的精准推导。

为什么不能用keyof T[keyof T]作为secondKey的类型?

T[keyof T]表示的是T中所有属性值的联合类型,在你的例子里就是{a: true, b:2} | {c:"12", d:18}。

而keyof作用于联合类型时,只会返回所有类型共有的key(也就是交集)。你的例子里两个子对象的keya/b和c/d没有任何交集,所以keyof ({a: true, b:2} | {c:"12", d:18})的结果就是never——这就是为什么代码会报错secondKey为never类型。

换个场景,如果两个子对象有共同key,比如foo和bar都有x属性,那keyof T[keyof T]会是x,但这依然无法实现firstKey和secondKey的关联:比如你传入firstKey为foo,secondKey却能传x之外的a,这显然不符合逻辑。

内容的提问来源于stack exchange,提问作者Jason Ch.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 04:33:37