Следующий машинописный код компилируется просто отлично:
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
.
Так что мой вопрос будет, если есть разумная причина, почему вывод типа ведет себя по-разному в случае троичного оператора?