Утверждение типа¶
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, чтобы можно было их использовать.