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

TypeScript对象属性赋值报错:string|number无法赋值给never

为什么第二个循环会报Type 'string | number' is not assignable to type 'never'?

咱们先把你的代码场景摆出来,方便对照分析:

const obj1 = { name: 'bob', age: 18 }
const obj2 = { name: 'tom', age: 19 }

// 第一个循环:类型不匹配报错,你已经理解了
for (const key in obj1) { obj1[key] = obj2[key] }

// 第二个循环:出现你困惑的never类型报错
for (const key in obj1) { 
  type Key = keyof typeof obj1 
  obj1[key as Key] = obj2[key as Key] 
}

// 第三个循环:解决了问题
for (const key in obj1) { 
  type Key = keyof typeof obj1 
  type Value = typeof obj1[Key] 
  (obj1[key as Key] as Value) = obj2[key as Key] 
}

核心原因:TypeScript无法追踪循环中key的具体类型绑定

当你把key断言为Key(也就是"name" | "age")时,TypeScript知道obj1[key as Key]的类型是string | number,obj2[key as Key]也是string | number——但它没办法在循环的每一次迭代里,把当前的key和对应的值类型做精准绑定。

举个例子:假设这一次循环key是"name",obj1["name"]是string类型,但TypeScript只知道obj2[key as Key]可能是string或number,它不能保证两者类型完全一致(比如万一obj2["name"]变成了数字呢?虽然你的代码里不是,但TypeScript要做静态检查)。

为了避免这种潜在的类型不匹配风险,TypeScript会把obj1[key as Key]的类型推断为never——因为不存在一个类型既能接受string又能接受number,同时还严格符合obj1中对应key的原始类型约束。所以当你试图把string | number赋值给never类型时,就触发了那个报错。

为什么第三个循环能解决问题?

第三个循环里,你显式声明了type Value = typeof obj1[Key],然后把obj1[key as Key]断言为Value——这相当于你在告诉TypeScript:“我确认当前迭代的key对应的obj1值类型,和obj2对应key的类型完全匹配”。通过这个断言,TypeScript放宽了类型检查,允许赋值操作。

额外的类型安全写法

其实还有更简洁的方式,用泛型函数来帮TypeScript追踪具体的key类型:

function assignKey<K extends keyof typeof obj1>(target: typeof obj1, source: typeof obj2, key: K) {
  target[key] = source[key];
}

for (const key in obj1) {
  assignKey(obj1, obj2, key as keyof typeof obj1);
}

泛型函数会在每次调用时,把K绑定到当前迭代的具体key类型(要么是"name",要么是"age"),这样TypeScript就能精准确认赋值的类型匹配,不需要额外的类型断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:28:11