Каждый разработчик сталкивался с преобразованием строк в числа, но немногие осознают, насколько разные грабли скрываются за
parseInt и Number. В production эта тема критична при валидации user input, парсинге API-ответов или обработке CSV. Типичная ошибка — полагаться на один метод без учета edge-кейсов, что приводит к молчаливым потерям данных или скрытым багам в финансовых, аналитических или гео-сервисах.Разные ожидания от одного преобразования
parseInt('100px') → 100. Он игнорирует хвост, что удобно для CSS, но убивает, когда требуется строгая валидация. Number('100px') → NaN. Уже противоречие. Выбери не тот метод — и production упадет или, что хуже, обработает мусор. Запомни: Number строже, parseInt терпимее к префиксам, но оба обманывают на пустых строках.Молчаливые нули и бесконечности
Number('') → 0. Пустая строка в JSON-валидации становится нулем, и ты считаешь то, чего нет. Number(' \t\n') → тоже 0. Особенно опасно в формах, где пробелы — частый сценарий. parseInt(Infinity) → NaN, а Number(Infinity) → Infinity. Разное поведение на одних данных, совместимое с TS-типами, но ломающее бизнес-логику.Legacy восьмерички и запятые
В старых браузерах
parseInt('010') мог вернуть 8. Сейчас стандарт parseInt требует основание 10, но если есть legacy, не расслабляйся. Еще одна ловушка: parseInt('1,000') → 1. Запятая игнорируется, и тысяча превращается в единицу. Для CSV или локализованных чисел это катастрофа. Используй Number с replace запятых или Intl.NumberFormat.Практический совет: кастомный тип для safe parsing
В sharing types для API или валидации полей вводи явный тип:
type SafeNumber = number | 'NaN' | 'Inf'
function parseNumericInput(value: unknown): SafeNumber {
if (typeof value === 'number' && !isNaN(value)) return value
if (typeof value !== 'string') return 'NaN'
const trimmed = value.trim()
if (trimmed === '') return 'NaN'
const num = Number(trimmed)
if (isNaN(num)) return 'NaN'
if (!isFinite(num)) return 'Inf'
return num
}
Это не спасет от всех граблей, но делает неявное явным. В JSON.parse можно передать reviver, проверяющий строки "NaN" и "Infinity". Без него такие значения пройдут как строки, сломав runtime-ожидания.
Вывод: В production всегда используй кастомные утилиты с явной обработкой пустых строк, Infinity и строковых NaN, а не прямые вызовы parseInt или Number — это убережет от невидимых дефектов в числовых данных.