TypeScript报错:Type 'string'不可赋值给type 'never'原因解析
TypeScript报错解析:Type 'string | number' is not assignable to type 'never'
问题场景
以下代码尝试将类型B的属性合并到A & B类型的变量result中,但TypeScript抛出类型不兼容错误:
type A = { a: number, b: string, c: true, d: number[], e: null, f: { a: number, b: string } }; type B = { a: number, g: string }; const A: A = { a: 1, b: "2", c: true, d: [1, 2, 3], e: null, f: { a: 1, b: "" } }; const B: B = { a: 2, g: "123" }; let result = A as (A & B); (Object.keys(B) as Array<keyof B>).forEach( key => result[key] = B[key] );
错误提示
Type 'string | number' is not assignable to type 'never'.
Type 'string' is not assignable to type 'never'.
核心原因
TypeScript在处理动态键的类型推导时,无法精准关联每个key对应的具体类型,具体逻辑如下:
key的类型是keyof B,即联合类型"a" | "g"。- 对于
result[key],TypeScript会计算所有可能键对应的类型交集:- 当
key为"a"时,result["a"]的类型是A["a"] & B["a"],即number & number = number; - 当
key为"g"时,A中不存在g属性,所以A["g"]是never,result["g"]的类型为never & string = never。
- 当
- 综合两种情况,
result[key]的最终类型被推断为number | never = never(never是所有类型的子类型,联合后会被吸收)。 - 而
B[key]的类型是B["a"] | B["g"] = number | string,将number | string赋值给never必然触发类型错误。
简言之:循环中TypeScript无法为每个key单独推导类型,只能取所有情况的交集,导致目标类型收缩为never。
解决办法
方法1:用泛型函数精准推导类型
通过泛型函数让TypeScript为每个键单独推导类型:
function assignKey<T, K extends keyof T>(obj: T, key: K, value: T[K]) { obj[key] = value; } (Object.keys(B) as Array<keyof B>).forEach( key => assignKey(result, key, B[key]) );
方法2:类型断言跳过检查(谨慎使用)
如果你能确保代码的类型安全性,可以用类型断言绕过TypeScript的检查:
(Object.keys(B) as Array<keyof B>).forEach( key => (result[key] as unknown) = B[key] );
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

