Может ли переменная B иметь тип, отличный от числа?
Что проверяют
Знаете ли вы, какие типы бывают в JavaScript и как операции их меняют. Вопрос почти всегда идёт к куску кода: интервьюер хочет, чтобы вы проследили, откуда берётся значение B. Следом спрашивают, спасёт ли TypeScript.
Как отвечать
Да. В JavaScript тип принадлежит значению, а не переменной, и let B сегодня хранит число, а завтра строку. Типов восемь: семь примитивов (undefined, null, boolean, number, bigint, string, symbol) и object, куда входят массивы и функции.
Дальше разберите выражение, из которого получено B:
- сложение со строкой:
"5" + 1даёт"51", строку. Значение изinput.value,URLSearchParamsилиlocalStorageвсегда строка, даже если там цифры; - остальная арифметика:
"5" * 1и"5" - 0приводят к числу, а"abc" * 1даётNaN, у которогоtypeofтоже"number"; - BigInt:
10n + 1nимеет типbigint, а смешивание10n + 1бросаетTypeError; - пустое значение:
let B;без присваивания даётundefined, функция безreturnтоже возвращаетundefined.
Проверять тип стоит так: typeof для примитивов, Array.isArray для массивов, Number.isNaN вместо глобального isNaN, который сначала приводит аргумент к числу.
Про TypeScript: аннотация let B: number запрещает присвоить строку при компиляции, но после сборки типов нет. Данные из JSON.parse, ответа API или приведения через as в рантайме могут оказаться чем угодно, поэтому внешние данные проверяют схемой, например через Zod.
Где спотыкаются
Говорят, что typeof [] вернёт "array". Вернёт "object", как и typeof null, и это частый уточняющий вопрос.
Считают NaN чем-то «не числового» типа. По типу это как раз число, поэтому проверка typeof B === "number" его пропускает.
Уверены, что TypeScript гарантирует тип во время выполнения. Он проверяет только код, который видит компилятор, а any и непроверенный ответ сервера обходят его молча.