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

为何TypeScript中泛型函数内的索引类型被推断为never?

问题分析

先看你给出的代码:

type X = { aa: number; bb: string };
const get = <Key extends keyof X>(key: Key) => {
  type T<Value extends X[Key]> = Value;
  const a: T<any>;
  /**
   * 类型“string”不满足约束“X[Key]”。
    类型“string”不能赋值给类型“never”。
   */
  const b: T<string>; 
};

核心原因:泛型参数的作用域与类型收缩

  1. 外层泛型Key的特性:get函数的泛型Key是调用时确定的单一类型,它要么是"aa"要么是"bb",而非同时包含两者的联合类型。在函数内部编写代码时,TypeScript并不知道Key最终会是哪一个具体值,只会把它当成一个「未知的特定键」。
  2. X[Key]的类型推导:因为Key是未知的特定键,X[Key]对应的是单一类型(要么number要么string),而不是number | string。当你尝试给内部泛型T传入string时,TypeScript需要验证string是否能满足X[Key]的约束——但由于Key可能是"aa"(此时X[Key]是number),string无法同时适配number和string两种可能的约束,所以TypeScript会取两种约束的交集:number & string,而这个交集的结果就是never。
  3. 你误解的点:你以为X[Key]是number | string,但实际上在泛型函数内部,Key是「单一值的占位符」,不是联合类型,所以X[Key]也不会是联合类型。只有当直接把Key写成keyof X时,X[keyof X]才会是number | string。

验证示例

把get函数的调用场景具体化,就能看清楚逻辑:

  • 当调用get("aa")时,Key是"aa",X[Key]是number,此时T的约束就是number,传入string自然会报错;
  • 当调用get("bb")时,Key是"bb",X[Key]是string,此时T<string>是完全合法的。

但在函数内部编写代码时,TypeScript必须保证代码能适配所有可能的Key值,所以它不会假设Key是某一个特定值,而是取所有可能情况的交集,最终得到never。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:01:17