【发布时间】:2019-04-16 09:08:44
【问题描述】:
以下打字稿代码编译得很好:
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);
}
但是,这个语义上等价的代码却没有:
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);
}
x !== 1 的错误是:
7:17 error TS2367: This condition will always return 'true' since the types '0' and '1' have no overlap.
在这两种情况下,运行编译结果都会产生预期的输出,表明 x 实际上取值 0 和 1:
0
1
0
我理解错误源于编译器在第二种情况下将0 | 1 类型缩小为0。但是,仅通过查看代码就很清楚 可能 x 被分配了 1(即使没有查看条件)。因此,除非另有明确说明(如第一个示例中那样),否则我希望类型推断采用最通用的类型。事实上,在第 1 行我明确告诉编译器我想要更通用的类型:let x: 0 | 1。
所以我的问题是,在三元运算符的情况下,类型推断的行为不同是否有合理的原因?
【问题讨论】:
标签: typescript ternary-operator union-types