TypeScript交叉运算符(&)编译报错疑问:为何未包含非交叉属性?
TypeScript交叉类型与条件类型结合的编译错误疑问
代码示例
interface ResultBase { readonly success: boolean } type Result<Payload = undefined> = ResultBase & (Payload extends undefined ? { readonly payload?: unknown } : { readonly payload: Payload }) function getResult<Payload = undefined>(payload: Payload): Result<Payload> { return { // ^^^^^^ success: true, payload, } }
编译错误信息
Type '{ success: true; payload: Payload; }' is not assignable to type 'Result<Payload>'. Type '{ success: true; payload: Payload; }' is not assignable to type 'Payload extends undefined ? { readonly payload?: unknown; } : { readonly payload: Payload; }'.
疑问点
为什么错误信息里的条件类型没有包含success属性?按道理该属性应该通过ResultBase & …的交叉类型被包含进来才对?
这是因为TypeScript在处理泛型条件类型的交叉赋值检查时,会优先拆解交叉类型,把检查焦点放在不匹配的条件类型分支上,而不会自动将ResultBase的属性合并到错误提示的条件类型里。
具体来说,Result<Payload>是ResultBase和条件类型的交叉,TypeScript检查返回值时会验证两个部分:
- 返回值包含
success: boolean属性(这部分你的代码其实已经满足) - 返回值符合条件类型的分支结果
错误提示里只展示条件类型部分,是因为TypeScript已经确认success属性符合要求,问题出在条件类型与返回值payload的匹配上,所以仅针对不匹配的分支做提示。
另外,这个错误的本质是泛型条件类型的延迟解析问题,你可以通过调整Result的定义来修复:
type Result<Payload = undefined> = Payload extends undefined ? ResultBase & { readonly payload?: unknown } : ResultBase & { readonly payload: Payload }
把交叉类型放到条件类型的每个分支中,让TypeScript能清晰解析每个分支的完整结构,赋值检查即可正常通过。
内容的提问来源于stack exchange,提问作者Parzh
相关产品推荐
相关产品推荐

