简体   繁体   English

打字稿:联合类型和三元运算符的类型推断

[英]Typescript: Type inference with union types and ternary operator

The following typescript code compiles just fine: 以下打字稿代码可以正常编译:

let x: 0 | 1 = 0;

console.log(x);

const r = [true, false];
for (const y of r) {
    if (y || (x !== 1)) {
        x = 1;
    } else {
        x = 0;
    }

    console.log(x);
}

However this code, which is semantically equivalent does not: 但是,此代码在语义上是等效的,它不会:

let x: 0 | 1 = 0;

console.log(x);

const r = [true, false];
for (const y of r) {
    x = ((y || (x !== 1)) ? 1 : 0);
    console.log(x);
}

Error for the x !== 1 is: x !== 1错误是:

7:17 error TS2367: This condition will always return 'true' since the types '0' and '1' have no overlap.

In both cases, running the compiled result yields the expected output showing that x does in fact take the value 0 and 1: 在这两种情况下,运行编译结果都会产生预期的输出,表明x实际上确实取值0 1:

0
1
0

I understand the error stems from the fact that the compiler narrowed down the type 0 | 1 我理解错误源于编译器缩小了类型0 | 1的事实0 | 1 0 | 1 to just 0 in the second case. 在第二种情况下为0 | 10 However, just by looking at the code it is clear that it could be that x is assigned 1 (even without looking at the condition). 然而,仅仅通过看代码很明显,这可能是因为x分配1(即使不看条件)。 Thus, I would expect type inference to assume the most general type unless explicitly told otherwise (as it does in the first example). 因此,除非另有明确说明,否则我希望类型推断采用最通用的类​​型(如第一个示例中所述)。 In fact, in line 1 I explicitly tell the compiler that I want the more general type: let x: 0 | 1 实际上,在第1行中,我明确告诉编译器我需要更通用的类型: let x: 0 | 1 let x: 0 | 1 . let x: 0 | 1

So my question would be if there is a sensible reason why the type inference behaves differently in case of the ternary operator? 因此,我的问题是,如果存在明智的理由,那么对于三元运算符,类型推断的行为会有所不同?

The error is actually because the compiler has narrowed the type of x to 0 . 该错误实际上是因为编译器将x的类型缩小为0

I'm not sure why you don't get the error in the other case - as I would expect it to be consistent in both cases - but I'm not smart enough to write the tools that do this stuff. 我不确定在其他情况下为什么没有收到错误-我希望在两种情况下都能保持一致-但是我不够聪明,无法编写执行此操作的工具。

Example where the type of x is forced to be 0 | 1 x的类型强制为0 | 1示例 0 | 1 rather than the compiler narrowing it to zero: 0 | 1而不是编译器将其范围缩小为零:

let x = 0 as 0 | 1;

console.log(x);

const r = [true, false];
for (const y of r) {
    x = ((y || (x !== 1)) ? 1 : 0);
    console.log(x);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM