TypeScript中对象展开返回类型为何保留undefined/null?报错解析
TypeScript合并函数编译错误分析与解决
这是TypeScript类型系统的固有限制,并非你的写法错误。
错误原因
当泛型A或B是null/undefined时,A & B可能包含空值类型。虽然运行时{...a, ...b}会自动忽略空值,但TS的静态类型检查无法识别这种展开操作对可空类型的过滤逻辑,因此无法推导出结果符合A & B & {}的约束,进而抛出赋值错误。
可行解决方案
方案1:类型断言直接绕过检查
既然你明确知道展开结果符合预期类型,用断言告知TS即可:
function merge<A extends object | undefined | null, B extends object | undefined | null>(a: A, b: B): A & B & {} { return { ...a, ...b, } as A & B & {}; }
方案2:优化条件类型写法并结合断言
你尝试的(A extends {} ? A : {}) & (B extends {} ? B : {})思路是合理的,但同样需要断言辅助TS识别:
function merge<A extends object | undefined | null, B extends object | undefined | null>( a: A, b: B ): (A extends {} ? A : {}) & (B extends {} ? B : {}) { return { ...a, ...b, } as ReturnType<typeof merge<A, B>>; }
方案3:使用内置工具类型简化返回值
如果目标是排除null/undefined,直接用TS内置的NonNullable工具类型更直观,效果和A & B & {}一致:
function merge<A extends object | undefined | null, B extends object | undefined | null>(a: A, b: B): NonNullable<A> & NonNullable<B> { return { ...a, ...b, } as NonNullable<A> & NonNullable<B>; }
补充说明
undefined & {}或null & {}确实等价于never,这意味着当传入的a和b均为空值时,返回类型会变成never——这符合逻辑,因为合并空值无法得到有效对象。- 这类问题本质是TS静态类型系统无法完全跟踪运行时的动态行为,属于当前版本的局限性。
内容的提问来源于stack exchange,提问作者TN.
相关产品推荐
相关产品推荐

