Возможно, вы неправильно поняли, что TypeScript 2.0 и выше имеет функцию, называемую анализ типов на основе потока управления , реализованный в microsoft / TypeScript # 8010 . Одним из эффектов этой функции является то, что
Присвоение (включая инициализатор в объявлении) значения типа S
переменной типа T
изменяет тип этой переменной до T
, суженного на S
в пути кода, который следует за назначением. [...] Тип T
, суженный на S
, вычисляется следующим образом: [...] Если T
является типом объединения, результатом является объединение каждого составного типа в T
, которому можно назначить S
.
Это означает, что оператор
let oscar: Animal = 'dog';
интерпретируется как: "переменная oscar
имеет тип Animal
, тип объединения. Ему было присвоено значение строкового литерала типа "dog"
, поэтому до его переназначения мы будем обрабатывать переменную oscar
как тип Animal
, суженный на "dog"
Это просто "dog"
.
И поэтому в вашем switch
/ case
выражении:
case 'bird': // error!
// ~~~~~~ <-- Type '"bird"' is not comparable to type '"dog"'
Вы получаете ошибку при попытке сравнить строковый литерал "bird"
строковому литералу "dog"
. Компилятор знает, что регистр 'bird'
невозможен, поскольку вы не переназначили oscar
на что-либо, совместимое с 'bird'
.
Даже в вашем wizard
случае Компилятор понимает, что когда он достигает оператора switch
/ case
, oscar
может быть только "cat"
или "dog"
, а не * 10 56 *:
case 'bird': // error!
// ~~~~~~ <-- Type '"bird"' is not comparable to type '"cat" | "dog"'
Это, наверное, хорошие новости; компилятор ловит случаи, которые никогда не могут произойти. Для многих ситуаций это настоящие ошибки.
Если вы хотите, чтобы компилятор не осознавал, что oscar
определенно "dog"
, а знал только, что это Animal
(как, скажем, заполнитель, пока вы не напишите код, который делает возможным для него быть любым членом Animal
), вы можете использовать утверждение типа в самом присваивании:
let oscar: Animal = 'dog' as Animal;
Теперь весь ваш другой код будет скомпилировать без ошибок. Вы даже можете забыть аннотацию, поскольку она вам не помогла:
let oscar = 'dog' as Animal;
Хорошо, надеюсь, это поможет; удачи!
Детская площадка ссылка на код