Typescript 操作员'==';不能应用于类型";“A”字&引用;“B”;,但是'===';可以
我已经读过了,但它并没有为我的案例提供信息 在TypeScript 2.5.3中,我们使用以下形式的字符串枚举定义了许多模型:Typescript 操作员'==';不能应用于类型";“A”字&引用;“B”;,但是'===';可以,typescript,if-statement,typescript-2.5,Typescript,If Statement,Typescript 2.5,我已经读过了,但它并没有为我的案例提供信息 在TypeScript 2.5.3中,我们使用以下形式的字符串枚举定义了许多模型: export interface Event { category: "MORNING" | "NIGHT"; enabled: boolean; } 然后对其应用比较器,如: morning = events.filter(event => event.category === 'MORNING'); 毫无怨言 现在,在这个代码片段中: if (
export interface Event {
category: "MORNING" | "NIGHT";
enabled: boolean;
}
然后对其应用比较器,如:
morning = events.filter(event => event.category === 'MORNING');
毫无怨言
现在,在这个代码片段中:
if (event.enabled || event.category === 'MORNING') {
// something
}
else if (event.category !== 'MORNING') {
// something else
}
我得到了操作符'!='不能应用于else if
条件中的类型“MORNING”和“NIGHT”
编译错误,但不能应用于使用相同(但相反)比较器的if
条件中的类型
进一步简化示例,编译如下:
if (event.category !== 'MORNING') {
// something
}
else if (event.category !== 'MORNING') {
// something else
}
if (event.category !== 'MORNING') {
// something
}
else if (event.category === 'MORNING') {
// something else
}
这包括:
if (event.category !== 'MORNING') {
// something
}
else if (event.category !== 'MORNING') {
// something else
}
if (event.category !== 'MORNING') {
// something
}
else if (event.category === 'MORNING') {
// something else
}
然而,这会抛出一个错误(在else if
行中):
我误解了类型检查器的什么基本属性?
(注意:最后的示例是从更复杂的情况中缩减出来的,因此我不能使用简单的
else
)您会得到一个错误,因为编译器已经知道在else if
条件下,event.category
不是'MORNING'
,不再允许您将event.category
与之进行比较
如果此条件的计算结果为false
if (event.enabled || event.category === 'MORNING') {
// something
}
然后根据定义,事件.类别
不是'MORNING'
,因此是'NIGHT'
。编译器不允许您再次将其与'MORNING'
进行比较(实际上,再次将其与'MORNING'
进行比较是没有意义的),因为在计算条件时,已知它不是'MORNING'
顺便说一句,以下代码产生编译错误的原因基本相同:
if (event.category !== 'MORNING') {
// something
}
else if (event.category !== 'NIGHT') {
// something else
}
正如这一点:
if (event.category === 'MORNING' || event.category !== 'MORNING') {
// something
}
这是由于TypeScript在计算后续布尔表达式时“缩小”联合类型的方式造成的
正如下面评论中所建议的,请参阅,我认为这是正确的,与Typescript和TypeGuards中的类型检查系统有关。考虑:
你的第一个例子:
if (event.category !== 'MORNING') {
// something
}
else if (event.category === 'MORNING') {
// something else
}
在第一个if
typescript之后,不能假定任何关于类别的类型的信息。如果某个值不等于某个值,那么简单的检查并不能告诉我们变量的类型。在的下一个链中,如果,则它可以是与您的变量类型匹配的任何内容
不起作用示例:
if (event.category === 'MORNING') {
// something
}
else if (event.category !== 'MORNING') {
// something else
}
但是如果你反过来检查,你肯定知道category
不能等于'MORNING'
,所以Typescript会改变你的类型。这是某种类型的变窄
规范C中的更多信息:您的<代码>否则,如果
条件没有意义。如果条件是event.enabled | | event.category=='MORNING'
,那么根据定义,如果该条件不是真的,那么根据定义,event.category
是'NIGHT'
和event.category!='早晨“
是真的。为什么需要再次检查?如果这不是您实际需要检查的情况的准确表示,请给我们一个准确表示的示例。@JLRishe是对的;我已经尝试了每一种组合,只要你的条件不是多余的,而且有效。与类型缩小有关。发生这种情况的原因与您所链接的问题中的原因大致相同。@JLRishe确实如此,但正如我所解释的,这是一个简化的(相当人为的)示例,来自一个更复杂的决策矩阵,其中包含其他内容,我逐步删除这些内容以得出最终案例。在实际代码中,类别
也更复杂,但在构建my时,我注意到与提供的示例相同的行为。添加真正的代码墙不会增加问题的价值,因为我只想知道为什么会存在这三个最终案例。我很感谢您提供的答案是基于控制流的类型分析。:)我正在写一个更冗长的版本,但是现在我要放弃了!您可能想提到这是由于TypeScript的原因,这就是它如何缩小事件.category
。干杯谢谢你的解释!