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

TypeScript遍历赋值时fooType[K]无法赋值给barType[K]的问题

问题

需求:遍历foo的每个属性,检查bar中对应属性是否为nullish,若是则用foo的属性覆盖bar的对应属性。

代码示例:

type fooType = {
  a?: string
  b?: number
}

type barType = fooType & {
  c: string
}

const foo: fooType = {
  a: 'hello',
  b: 5,
}

const bar: barType = {
  a: 'greetings',
  b: undefined,
  c: 'not in foo',
}

const fooKeys = Object.keys(foo) as Array<keyof typeof foo>
fooKeys.forEach((k) => {
  bar[k] ??= foo[k]
})

初始报错:Type 'string' is not assignable to type 'never'。尝试泛型写法后,又出现报错:

Type 'fooType[K]' is not assignable to type 'barType[K]'.
  Type 'fooType' is not assignable to type 'barType'.
    Property 'c' is missing in type 'fooType' but required in type '{ c: string; }'.

解决方法

错误原因

TypeScript处理交叉类型barType = fooType & {c: string}时,无法自动推断fooType的属性与barType对应属性的类型兼容性;同时Object.keys的类型断言虽然拿到了keyof fooType,但TypeScript无法确认bar[k]和foo[k]的类型完全匹配,导致类型检查报错。

方案一:类型断言快速修复

直接在赋值时添加类型断言,明确告知TypeScript两者类型兼容:

const fooKeys = Object.keys(foo) as Array<keyof typeof foo>
fooKeys.forEach((k) => {
  (bar[k] as typeof foo[k]) ??= foo[k]
})

这种方式简单直接,适合快速解决问题,但需要自行确保类型确实兼容。

方案二:泛型函数约束类型

通过泛型约束让TypeScript明确bar包含foo的所有属性,从而正确推导类型:

function mergeNullishProps<F, B extends F>(foo: F, bar: B) {
  (Object.keys(foo) as Array<keyof F>).forEach((k) => {
    bar[k] ??= foo[k]
  })
}

mergeNullishProps(foo, bar)

这里B extends F确保bar的属性集合包含foo的所有属性,TypeScript能准确识别每个键对应的类型,不会再出现兼容性错误。

方案三:手动指定键类型

如果不想用泛型,手动列出fooType的键并指定类型,避免Object.keys带来的类型模糊问题:

type FooKeys = keyof fooType
const fooKeys: FooKeys[] = ['a', 'b']
fooKeys.forEach((k) => {
  bar[k] ??= foo[k]
})

手动指定键数组的类型后,TypeScript能精确匹配每个键对应的属性类型,顺利通过类型检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:10:50