Typescript 操作员'==';不能应用于类型";“A”字&引用;“B”;,但是'===';可以

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 (

我已经读过了,但它并没有为我的案例提供信息

在TypeScript 2.5.3中,我们使用以下形式的字符串枚举定义了许多模型:

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
。干杯谢谢你的解释!