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
答案 0 :(得分:10)
为什么不将5和2视为类型'数字'
具有文字类型5
和2
。例如
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 :)