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
相关产品推荐
相关产品推荐

