История вопроса:
TypeScript реализует статическую типизацию, поэтому иногда требуется явно преобразовать один тип в другой. Например, когда разработчик знает структуру данных лучше компилятора или когда нужно работать с типизированным API, исходящий типы которого не совпадают с ожидаемыми. Для этого используется механизм type casting, или assert типов.
Проблема:
Приведение типов (type casting) в TypeScript не делает никаких преобразований значений на уровне исполнения: оно лишь сообщает компилятору "доверься мне". Это может привести к ошибкам, если указанный каст не соответствует реальному содержимому данных. Ошибки появятся только в рантайме, и их не выявит компилятор.
Решение:
В TypeScript включены два синтаксиса приведения типов: angle-bracket (устаревший, не рекомендуется для JSX) и as-синтаксис (рекомендованный).
Пример кода:
// Синтаксис через угловые скобки (не для .tsx) let someValue: any = "Hello World"; let strLength: number = (<string>someValue).length; // Синтаксис через as let strLength2: number = (someValue as string).length; // Приведение типа объекта (unsafe!) interface Cat { meow(): void; } interface Dog { bark(): void; } let dog: Dog = { bark() {} }; let cat = dog as unknown as Cat; // так можно, но это обходит типизацию!
Ключевые особенности:
Делает ли type assertion автоматическое преобразование значений в рантайме, как в C# или Java?
Нет, type assertion лишь подсказывает компилятору, что переменная этого типа. Никакое преобразование значений не происходит — ответственность полностью на разработчике.
Можно ли привести тип A к типу B без общей структуры?
TypeScript позволит это (через двойной cast, например any или unknown), но это подрывает безопасность типов и может привести к ошибкам на этапе исполнения.
const a = 5 as unknown as string; // не безопасно!
Безопасно ли приводить any к сложному типу?
Нет, any отключает проверку типов: приведение any к другому типу возможно, но TypeScript не сможет отловить несоответствия, любые ошибки проявятся только при исполнении.
Разработчик получает объект с сервера без проверки структуры, приводит его к ожидаемому типу элементарным as SomeType и использует в бизнес-логике. При изменении API или баге на сервере приложение падает в рантайме, без ошибок на этапе сборки.
Плюсы:
Минусы:
Разработчик предварительно валидирует структуру полученного объекта, используется пользовательская type guard-функция и только после успешной проверки происходит type assertion.
Плюсы:
Минусы: