为何TypeScript中0 | "" | {} extends 0 | ""返回false?
TypeScript联合类型extends判断逻辑解析
先看你给出的代码示例:
0 | "" | {} extends 0 | "" // false 0 | "" | {} extends 0 | {} // true
核心规则:联合类型的分配式检查
TypeScript中,联合类型的extends判断不是简单的集合包含关系,而是遵循分配式检查逻辑:当执行UnionA extends UnionB时,TypeScript会把UnionA的每个成员单独取出,检查该成员是否能extendsUnionB中的至少一个成员。只有当UnionA的所有成员都通过该检查时,整个表达式才返回true。
拆解第一个表达式:0 | "" | {} extends 0 | ""
逐个验证左边联合的每个成员:
0 extends 0 | "":0是右边联合的成员,结果为true"" extends 0 | "":""是右边联合的成员,结果为true{} extends 0 | "":{}既不是数字类型0的子类型,也不是字符串字面量""的子类型,结果为false
由于存在一个成员不满足条件,整个表达式返回false。
拆解第二个表达式:0 | "" | {} extends 0 | {}
同样逐个验证左边联合的每个成员:
0 extends 0 | {}:0是右边联合的成员,结果为true"" extends 0 | {}:TypeScript中{}类型代表除null和undefined之外的所有值类型,原始类型(如字符串"")可以extends{},因此"" extends {}为true,进而"" extends 0 | {}也为true{} extends 0 | {}:{}是右边联合的成员,结果为true
所有成员都满足条件,因此整个表达式返回true。
额外说明:避免分配式检查
如果想跳过分配式检查,直接比较两个联合类型的集合包含关系,可以将联合类型包裹在元组中,比如:
[0 | "" | {}] extends [0 | ""] // true
此时TypeScript会将整个元组作为单一类型比较,而非拆分成员检查。
内容的提问来源于stack exchange,提问作者MetalMentos
相关产品推荐
相关产品推荐

