为什么类型收缩在这些代码段中不起作用?
const xyz: { num: number } | { str: string }
if ("num" in xyz) {
xyz // { num: number; } | { str: string; }
}
我甚至尝试添加一个类型判别式:
const xyz: { type: "num", num: number } | { type: "str", str: string }
if (xyz.type === "num") {
xyz // { type: "num", num: number } | { type: "str", str: string }
}
我使用的是Typescript版本5.0.2
2条答案
按热度按时间7hiiyaii1#
看起来当Typescript类型检查器抱怨先前的错误或警告时,可能会抛出正确的类型收缩。
在我的例子中,解决方案是修复(或静默)未初始化变量
xyz
的使用(以及其他先前的类型错误),类型收缩再次正常工作。看似无关的类型错误会使类型检查器处于糟糕的状态;确保在处理任何奇怪的错误之前先修复简单的错误。
ijnw1ujt2#
类型窄化在示例中不起作用,因为
{ num: number } | { str: string } and { type: "num", num: number } | { type: "str", str: string }
的类型联合不是互斥的,这意味着该类型的变量可以具有属于两个联合成员的属性。在第一个示例中,即使您检查了xyz中的“num”,xyz仍然可以是
{ str: string }
类型。这是因为xyz可以有属性str:字符串,它是第二个联合成员的成员。类似地,在第二个示例中,检查
xyz.type === "num"
仅将类型缩小到{ type: "num", num: number } | { type: "str", str: string }
,而不是特定类型。因此,xyz仍然可以具有属性str: string
。要在这些示例中进行类型收缩,需要使用类型保护,它可以将类型缩小到联合体的特定成员。例如,你可以像这样定义一个自定义类型保护函数:
然后你可以在代码中使用这个类型保护来缩小xyz的类型:
类似地,对于第二个例子,你可以像这样定义一个类型保护函数:
然后你可以在代码中使用这个类型保护来缩小xyz的类型: