运算符'=='不能应用于Typescript 2中的类型x和y

时间:2016-08-31 07:19:45

标签: typescript type-conversion typescript2.0

TypeScript版本: 2.0.2.0

代码 我知道代码有点愚蠢,但我实际上在我的代码中有这样的测试(制作表达式访问者),我真的认为这些应该立即飞行并编译。

var a: boolean = (true == false);
var b: boolean = (5 == 2);

相反,它抱怨操作数相等不能应用于类型'true','false','5'和'2'。标记它们不是布尔值或数字,它们实际上是'true','false','5','2'的类型。我知道类型'string'和'boolean'无法比较,但是嘿,5实际上是一个数字,不是'5'类型,还是我弄错了?

这可以编译。

let x = 2;
var a: boolean = 5 == x;
var b: boolean = <number>5 == <number>2;

我错过了什么,为什么不将5和2视为类型'数字'?

预期行为 应该编译

实际行为 编译错误导致'操作数'=='无法应用于类型'&lt; first argument&gt;'和'&lt;第二个参数&gt;'

背景我在打字稿中遇到了这个问题,定义它应该是这样的,但是为什么会这样? https://github.com/Microsoft/TypeScript/issues/6167

4 个答案:

答案 0 :(得分:10)

  

为什么不将5和2视为类型'数字'

具有文字类型52。例如

var x: 5; 
// can only ever be assigned to 5 
x = 5; // okay 
x = 2; // Error 

我没有看到一个实际的用例,希望它不是一个错误。这只是编译器试图帮助你。如果你看到足够的动力,请随意创建一个问题

答案 1 :(得分:8)

文字类型有许多优点,因为它允许编译器使类型尽可能窄。您的用例很少出现,但希望类型尽可能地缩小,贯穿整个语言设计。所以,是的,虽然它使你的生活在这个特定的案例中更难,但它在整个语言中是有意义的。用户将不得不遭受更糟糕的语言,只是为了支持这一个罕见的用例。

不幸的是,您必须在第二个示例中使用您自己建议的显式输入。我没有看到它被修复,因为大多数用户想要语言如果他们试图这样做就会大喊大叫。它可能是大多数情况下出现错误的迹象。

答案 2 :(得分:4)

作为Erlang开发人员,我曾经在Erlang中看到过这种错误,但不确定它在TypeScript中意味着什么,这里有一个例子可以帮助你理解这个问题:

let answer: "yes" | "no" | "maybe" = "yes";
if (Math.random() > 0.5) {
    answer = "maybe";
}

if (answer === "yes") {
    console.log('yes');
}

if (answer === "no") {
    console.log('no');
}

它不会编译错误:

error TS2365: Operator '===' cannot be applied to types '"yes" | "maybe"' and '"no"'.

首先,这里有解决方案

let answer = "yes" as "yes" | "no" | "maybe";

现在解释:

由于此代码非常简单并且可以在编译时理解,因此TypeScript知道answer可能成为"no"的代码中没有位置,因此它只是对您说(虽然以相当神秘的形式表示,答案总是不是&#34;不是&#34;,所以根本没有理由去检查它是否是。但是(如在Erlang中)这可能是非常明显的原因,例如当你决定注释掉一些使answer成为"no"的调试代码时。现在,如果我们使用let answer = "yes" as "yes" | "no" | "maybe";let answer = <("yes" | "no" | "maybe")>"yes";,它将使TypeScript认为&#34;是&#34;可以&#34;不&#34;即使你无法在代码中看到它。因此,对于暂时​​删除的代码,第二个解决方案

if (0) {
    answer = "no";
}

即使这种情况永远不会成立,但它是复杂的&#34;足以让TypeScript编译器认为它可以是真的。我的Erlang方法是使用when X and not X if (x && !x) {,但至少在2.4中你可以使用数字表达式。

但在某些时候编译器可能是正确的,然后解决方案是删除对"no"的检查:)

因此,回到OP的问题,要使代码编译,您需要将其更改为:

var a = false;
var b = false;

如果编译器知道这一点,你可能也知道。

答案 3 :(得分:0)

Faced the same issue in a scenario as the following:

let a: string;

a === 'some-value1' && a === 'some-value2';  // <==

The second line produces the same error and maybe because Typescript is smart enough to know that a string type at a given moment cannot contain two (or more) different string literals.

The correct approach for the above expression would be to use OR in the expression:

a === 'some-value1' || a === 'some-value2';  // works fine :)