Средство проверки типа TypeScript выполняет анализ типа потока управления , что означает, что оно предпринимает усилия для определения того, что происходит со значениями внутри переменных во время выполнения, и сужает типы этих переменных для сопоставления. Один из конкретных способов это происходит, если у вас есть переменная или свойство тип объединения , и компилятор видит, что вы присваиваете ему более конкретно типизированное значение, он сузит тип переменной до этот более конкретный тип, по крайней мере, до тех пор, пока вы не назначите другое значение переменной.
Это очень часто желательно, так как он поддерживает следующие варианты использования:
let x: number | string = Math.random() < 0.5 ? "hello" : "goodbye"; // x is string now
if (x.length < 6) { // no error here
x = 0; // the widest x can be is string | number, so this assignment is fine
}
Обратите внимание, что даже если вы аннотировали , что x
является number | string
, компилятор понимает, что это определенно будет string
после первоначального назначения. Так что он не жалуется, когда вы проверяете x.length
(как если бы x
мог быть number
). Это настолько полезное поведение, что его отключение может привести к множеству реальных поломок кода TypeScript.
К сожалению, он также отвечает за поведение, которое вы здесь видите. После присвоения 5
value
компилятор видит value
как содержащую переменную суженного типа 5
. Не Prime
. Вы всегда можете расширить value
до Prime
, но компилятор не сделает этого автоматически. Он думает, что помогает вам, предупреждая, что вы звоните compare(5 as 5, 3)
, что запрещено.
В этом случае, как вы видели, единственный способ переопределить это поведение - это утверждение типа . Вы можете сделать это утверждение либо при первоначальном назначении, либо внутри вызова compare()
:
let value2: Prime = 5 as Prime
compare(value2, 3); // okay
let value3: Prime = 5;
compare(value3 as Prime, 3); // okay
Или вы можете вручную указать общий тип T
при вызове compare()
, который также работает:
let value4: Prime = 5;
compare<Prime>(value4, 3); // okay
Вам доступен любой из этих вариантов.
Наиболее каноническим источником документации, которую я могу найти для этого, является Microsoft / TypeScript # 8513 , и конкретно этот комментарий .
Хорошо, надеюсь, это поможет; удачи!
Ссылка на код