Утверждение типа¶
TypeScript позволяет вам переопределить прогнозируемое и проанализированное значение типов любым удобным для вас способом. Это делается с помощью механизма, называемого "утверждением типа". Простыми словами утверждение типа в TypeScript - это когда вы говорите компилятору, что вы знаете о типах лучше, чем он, и что он не должен сам догадываться.
Обычный вариант использования утверждения типа - это когда вы портируете код с JavaScript на TypeScript. Например, рассмотрим следующий шаблон:
1 2 3 |
|
Здесь ошибки в коде, потому что ожидаемый тип для foo
это {}
, т.е. объект без свойств. Поэтому вы не можете добавлять bar
или bas
к нему. Вы можете исправить это просто с помощью утверждения типа as Foo
:
1 2 3 4 5 6 7 |
|
as foo
против <foo>
¶
Первоначально был добавлен синтаксис <foo>
. Это продемонстрировано ниже:
1 2 |
|
Однако существует двусмысленность в грамматике языка при использовании утверждений в стиле <foo>
в JSX:
1 |
|
Поэтому сейчас рекомендуется просто использовать as foo
для единообразия.
Утверждение типа против приведения¶
Причина, по которой это не называется "приведением типа", заключается в том, что приведение обычно подразумевает некоторую поддержку среды выполнения. Тем не менее, утверждения типа - это просто конструкция для компиляции и способ для вас дать подсказки компилятору о том, как вы хотите, чтобы ваш код был проанализирован.
Утверждение считается опасным¶
Во многих случаях утверждение позволит вам легко перенести старый код (и даже скопипастить иные примеры кода в вашу кодовую базу). Тем не менее, вы должны быть осторожны с использованием утверждений. Возьмите наш исходный код в качестве примера, компилятор не защитит вас от того, что вы забудете добавить свойства, которые вы обещали:
1 2 3 4 5 6 |
|
Также другой распространенной идеей является использовать утверждения в качестве средства обеспечения автозаполнения, например:
1 2 3 4 5 6 7 8 9 10 |
|
но опасность здесь та же, если вы забудете свойство, компилятор не будет жаловаться. Лучше, если вы сделаете следующее:
1 2 3 4 5 6 7 |
|
В некоторых случаях вам может потребоваться создать временную переменную, но, по крайней мере, вы не будете давать (возможно, ложные) обещания и вместо этого будете полагаться на предполагаемый комилятором тип.
Двойное утверждение¶
Утверждение типа, несмотря на то, что, как мы показали, немного небезопасно, не является «чем-то абсолютно запрещённым». Например. следующее является очень даже допустимым случаем использования (например, пользователь думает, что переданное событие будет более конкретным случаем события), и утверждение типа работает как ожидалось:
1 2 3 |
|
Однако следующее, скорее всего, ошибка, и TypeScript будет жаловаться, как показано, несмотря на утверждение типа пользователем:
1 2 3 4 |
|
Если вы все еще хотите этот тип, вы можете использовать двойное утверждение, а именно сначала сделайте утверждение any
, которое совместимо со всеми типами, и поэтому компилятор больше не жалуется:
1 2 3 |
|
Как TypeScript определяет, что недостаточно одного утверждения¶
По сути, утверждение от типа S
к T
успешно выполняется, если либо S
является подтипом T
, либо T
является подтипом S
. Это делается для обеспечения дополнительной безопасности при выполнении утверждений типа ... совершенно безумные утверждения могут быть очень небезопасными, и вам нужно использовать any
, чтобы можно было их использовать.