运算符'!=='不能应用于类型“A”| “B”,但'==='可以吗?

时间:2017-11-03 17:08:44

标签: typescript if-statement typescript-2.5

我已阅读Operator '==' cannot be applied to types x and y in Typescript 2,但我的案例并没有提供信息。

在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
}

我在Operator '!==' cannot be applied to types '"MORNING"' and '"NIGHT"'条件中得到else if编译错误,但在<{1}}条件下没有,它使用相同(但相反)的比较器。

进一步减少示例,以下编译:

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 } 行中):

else if

我误解了类型检查器的基本属性?

(注意:最后的例子可以从更复杂的情况中减少,所以我不能使用简单的if (event.category === 'MORNING') { // something } else if (event.category !== 'MORNING') { // something else } 。)

2 个答案:

答案 0 :(得分:4)

您收到错误是因为编译器已经知道else if条件,event.category不是'MORNING'并且不再允许您比较{{1}对它来说。

如果此条件评估为event.category

false

然后根据定义,if (event.enabled || event.category === 'MORNING') { // something } event.category,因此'MORNING'。编译器不允许您再次将它与'NIGHT'进行比较(实际上再次将它与'MORNING'进行比较没有意义),因为已经知道它不是'MORNING'正在评估'MORNING'条件。

顺便说一句,以下内容产生编译错误的原因基本相同:

else if

就像这样:

if (event.category !== 'MORNING') {
 // something
}
else if (event.category !== 'NIGHT') {
 // something else
}

这是由于TypeScript在评估后续布尔表达式时“缩小”联合类型的方式。

根据以下评论中的建议,请参阅https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#control-flow-based-type-analysis以及https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#4.24

答案 1 :(得分:1)

我认为这是正确的,与Typescript和TypeGuards中的类型检查系统有关。考虑:

你的第一个例子:

if (event.category !== 'MORNING') {
 // something
}
else if (event.category === 'MORNING') {
 // something else
}

在第一个if打字稿后,不能假设category的类型。简单检查某些东西是否与某种值不相等,并没有告诉我们关于变量类型的任何信息。在else if的下一个链中,它可以是与您的变量类型匹配的任何内容。

不工作的例子:

if (event.category === 'MORNING') {
 // something
}
else if (event.category !== 'MORNING') {
 // something else
}

但如果你反过来检查,你肯定category不能等于'MORNING',所以Typescript会改变你的类型。它的某种类型缩小了。

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#424-type-guards更多信息,请参阅规范C: