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

TypeScript无法正确识别索引类型?参数类型不兼容问题咨询

问题原因分析

先贴出你的代码:

type X = {
  aa: string;
  bb: number;
};

const get = <Key extends keyof X, Value extends X[Key]>(
  key: Key,
  value: Value | ((v: Value) => Value)
) => {
  let newValue: Value;
  const x: X = {
    aa: '11',
    bb: 11
  };
  if (typeof value === 'function') {
    //Argument of type 'X[Key]' is not assignable to parameter of type 'Value'.
    newValue = value(x[key]);
  } else {
    newValue = value;
  }
};

你觉得X[Key]和Value完全一致,但TypeScript不这么认为——问题出在Value extends X[Key]这个泛型约束上:Value是X[Key]的子类型,而不是等价类型。

举个实际场景:假设有人这样调用你的函数:

get('aa', (v: '11') => v)

这里Key是'aa',X[Key]是string,而Value被推导成了字面量类型'11'(它是string的子类型)。此时x[key]的类型是string,但函数参数要求的是'11',string显然不能赋值给更具体的'11',所以TypeScript就抛出了报错。

简单说,你写的泛型允许Value比X[Key]更“窄”,但x[key]的类型是更“宽”的X[Key],自然无法兼容窄类型的参数要求。

解决方案

最直接的修复方式是去掉多余的Value泛型,直接用X[Key]来定义相关类型:

type X = {
  aa: string;
  bb: number;
};

const get = <Key extends keyof X>(
  key: Key,
  value: X[Key] | ((v: X[Key]) => X[Key])
) => {
  let newValue: X[Key];
  const x: X = {
    aa: '11',
    bb: 11
  };
  if (typeof value === 'function') {
    newValue = value(x[key]);
  } else {
    newValue = value;
  }
};

如果一定要保留Value泛型,那需要把约束改成等价关系,而不是继承:

const get = <Key extends keyof X, Value = X[Key]>(
  key: Key,
  value: Value | ((v: Value) => Value)
) => {
  // ... 后续逻辑不变
};

不过这种写法意义不大,因为Value默认就是X[Key],和直接用X[Key]效果一致。

内容的提问来源于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 13:10:49