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

TypeScript中为何键相同但值类型不同的类型无法用keyof互相索引

错误原因

你代码逻辑是对的,CompatType<T> 的键集合确实和 T 的键集合完全重叠,仅部分字段的类型不同。这个报错是 TypeScript 泛型推导能力的局限性导致的:泛型 T 在函数实际调用前是未知类型,TS 不会自动演算 Omit + 交叉类型 生成的 CompatType<T> 和原始 T 的键集合等价,因此不允许用 keyof T 直接索引 CompatType<T> 类型的变量。

解决方案

方案1:快速修复,增加类型断言

你明确知道键是合法的,直接在赋值时给键加类型断言即可:

export function compatModel<T>(model: T): CompatType<T> {
  const compat: Partial<CompatType<T>> = {};
  for (const k of Object.keys(model) as Array<keyof T>) {
    const v = model[k];
    // 把k断言为CompatType的键
    compat[k as keyof CompatType<T>] = typeof v === "bigint" ? v.toString() : v;
  }
  return compat as CompatType<T>;
};

方案2:优化类型定义,从根源解决

你可以把 CompatType<T> 改写为遍历所有键的映射类型,TS 可以直接识别这种写法下的键和 T 的键完全等价,不需要额外写断言:

// 保留原来的BigIntKeys逻辑,兼容你要严格匹配bigint类型的需求
export type CompatType<T> = {
  [P in keyof T]: P extends BigIntKeys<T> ? string : T[P]
};

// 改写后原来的函数代码不需要任何修改即可通过类型检查
export function compatModel<T>(model: T): CompatType<T> {
  const compat: Partial<CompatType<T>> = {};
  for (const k of Object.keys(model) as Array<keyof T>) {
    const v = model[k];
    compat[k] = typeof v === "bigint" ? v.toString() : v;
  }
  return compat as CompatType<T>;
};

这个写法和你原来的 Omit + 交叉类型 实现的效果完全一致,代码可读性也更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:15:03