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

如何让TypeScript识别正确索引键?解决类型赋值报错问题

解决TypeScript中索引赋值的类型不匹配问题

先看你的原代码:

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

const keys = ['aa', 'bb'] as (keyof Type)[];
const target = {} as {
  [Key in keyof Type]: Type[Key];
};

const source: Type = {
  aa: 'aa',
  bb: 123
};
keys.forEach((key) => {
  const s = source[key]; // string | number
  const t = target[key]; // string | number
  // 报错:Type 'string | number' is not assignable to type 'never'
  target[key] = source[key];
});

报错原因

TypeScript处理联合类型索引时,无法跟踪每次迭代中key的具体类型——它只知道key是'aa' | 'bb',因此source[key]的类型是string | number。而赋值时,TS会要求值的类型能匹配所有可能的target[key]类型,也就是取string和number的交集,结果是never,所以触发报错。

解决方案:用泛型函数保留类型关联

要让TypeScript识别key和对应值的类型绑定关系,可以用泛型函数遍历键,这样每次迭代的key会被推断为keyof Type的单个子类型,而非联合类型:

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

const keys = ['aa', 'bb'] as (keyof Type)[];
const target = {} as { [Key in keyof Type]: Type[Key] };
const source: Type = { aa: 'aa', bb: 123 };

// 泛型遍历函数,保留单个key的类型信息
function iterateKeys<T>(keys: Array<keyof T>, callback: <K extends keyof T>(key: K) => void) {
  keys.forEach(key => callback(key as K));
}

// 调用泛型函数遍历赋值
iterateKeys<Type>(keys, (key) => {
  target[key] = source[key]; // 类型匹配,无报错
});

简化方案:直接使用Object.assign

如果你的需求只是把source的所有属性复制到target,可以直接用Object.assign,它能自动处理类型匹配:

Object.assign(target, source); // 无类型报错,直接完成赋值

原理说明

泛型函数中的K extends keyof T会让TypeScript为每个迭代的key单独推断具体类型(比如第一次是'aa',第二次是'bb'),这样source[key]和target[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.12 01:05:46