Когда в JavaScript проверяются типы?
Что проверяют
Понимаете ли вы, что в JavaScript тип принадлежит значению, а не переменной, и что проверка происходит в момент выполнения операции. Следом обычно спрашивают про неявное приведение, разницу == и === и о том, что меняет TypeScript.
Как отвечать
До запуска движок проверяет только синтаксис: SyntaxError вылетает на этапе разбора, и файл не выполнится вовсе. Типы проверяются в рантайме, ровно тогда, когда выполнение доходит до операции:
- вызов не функции:
user.getName()при отсутствующем методе даётTypeError: ... is not a functionтолько на этой строке; - обращение к свойству
nullилиundefined: тожеTypeErrorв момент чтения, отсюда популярность?.; - присваивание константе:
TypeErrorпри выполнении, а не при разборе; - операторы с приведением:
"5" + 1склеивает строки,"5" * 2приводит к числу,==приводит по своему алгоритму,===сравнивает без приведения.
Для явных проверок есть typeof, instanceof и Array.isArray(). Движки вроде V8 собирают сведения о типах для оптимизаций и деоптимизируют код, когда типы меняются, но это про скорость, а не про корректность.
TypeScript проверяет типы на этапе сборки, а затем стирает их. В рантайме остаётся обычный JavaScript, поэтому данные извне (ответ API, localStorage, JSON.parse) приходится проверять схемой, например через Zod. Свежие версии Node.js умеют запускать .ts напрямую, но просто вырезают аннотации и ничего не проверяют.
Где спотыкаются
Говорят, что JavaScript не проверяет типы вообще. Проверяет, просто поздно: ошибка появится у пользователя на той ветке кода, до которой дошло выполнение.
Считают, что as User в TypeScript что-то гарантирует в рантайме. Это указание компилятору, и кривой ответ сервера пройдёт дальше без единой ошибки.
Путаются в typeof: typeof null и typeof [] дают "object", typeof NaN даёт "number". Массив проверяют через Array.isArray(), а null через === null.