Menu

TypeScript: строку в число и число в строку

Преобразование строки в число в TypeScript через Number(), parseInt(), parseFloat() или унарный +: как каждый способ обрабатывает "42px", "" и "1e3", как безопасно проверить NaN и как превратить число обратно в строку.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Чтобы преобразовать строку в число в TypeScript, вызовите Number(text). Результат имеет тип number и равен NaN, если текст не является корректным числом. Для текста с символами в конце, например "42px", используйте parseInt(text, 10) или parseFloat(text).

Все четыре преобразования возвращают тип number. TypeScript не знает, был ли текст корректным; некорректная строка всё равно даёт number, просто его значение равно NaN.

Почему преобразование обязательно

Поля форм, параметры URL, переменные окружения и содержимое файлов приходят строками. TypeScript не даст использовать строку там, где ожидается число:

index.ts(3,23): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Арифметика с -, * и / над строкой считается ошибкой. + разрешён, но склеивает строки, поэтому "3" + 10 даёт строку "310". Вот почему сначала нужно преобразование: Number(quantity) * 10.

Утверждение типа тоже не поможет. quantity as number отвергается (TS2352), а если протолкнуть его через as unknown as number, компилятор просто замолчит: во время выполнения значение останется строкой.

Number, parseInt, parseFloat и унарный плюс

На чистых данных все четыре функции дают одно и то же, а во всём остальном расходятся. В таблице реальный вывод каждой из них в Node:

ВводNumber(s)+sparseInt(s, 10)parseFloat(s)
"42"42424242
"3.99"3.993.9933.99
"42px"NaNNaN4242
""00NaNNaN
" 3 "3333
"1e3"1000100011000
"0x1F"313100
"1,000"NaNNaN11
"12_000"NaNNaN1212
"abc"NaNNaNNaNNaN

Правила, которые стоят за таблицей:

  • Number и унарный + работают одинаково. Они преобразуют всю строку после обрезки пробелов, понимают 1e3 и шестнадцатеричный 0x и возвращают NaN, если что-то осталось. Пустая строка или строка из одних пробелов превращается в 0.
  • parseInt и parseFloat читают с начала и останавливаются на первом символе, который не могут использовать, поэтому "42px" и "1,000" дают частичные числа. Пустая строка даёт NaN.
  • parseInt отбрасывает дробную часть и не понимает экспоненту: "1e3" обрывается на e.
  • Разделители разрядов (12_000) допустимы в исходном коде, но не в строках.

Для проверки ввода строже Number. parseInt и parseFloat подходят для текста, в котором действительно есть единица измерения или суффикс, например размеров в CSS.

Обработка некорректного ввода: NaN

NaN имеет тип number, поэтому компилятор о нём никогда не предупреждает. Проверяйте результат сами, через Number.isNaN или Number.isFinite:

Возвращаемый тип number | undefined делает ошибку частью типа, и каждый вызывающий код обязан её обработать, прежде чем считать. Number.isFinite к тому же отсекает Infinity, которое Number("Infinity") охотно возвращает.

Избегайте глобального isNaN(x): он сначала преобразует аргумент, поэтому в JavaScript isNaN("abc") равно true. Объявление в TypeScript принимает только number, так что передача строки даёт ошибку TS2345, и это намёк использовать Number.isNaN на уже преобразованном значении.

Строку в целое число

Всегда передавайте parseInt второй аргумент, основание системы счисления: 10 для десятичного текста. Он необязателен, но показывает намерение и важен для других оснований. Чтобы получить целое из десятичной строки, преобразуйте её, а затем явно округлите.

parseInt ожидает строку: parseInt(12.7) даёт ошибку компиляции (TS2345), и это полезно, потому что в JavaScript parseInt сначала превращает число в текст и выдаёт неверные ответы для значений вроде 0.0000005 (возвращает 5). Для чисел используйте Math.trunc. Для целых больше Number.MAX_SAFE_INTEGER BigInt(text) разбирает значение полностью (и на некорректном тексте бросает SyntaxError вместо того, чтобы вернуть NaN).

Число в строку

String(n), n.toString() и `${n}` одинаково превращают число в его кратчайшую строковую форму. Методы форматирования дают больше контроля:

toFixed округляет двоичное значение, а не то десятичное, которое вы написали, поэтому (1.005).toFixed(2) равно "1.00": 1.005 хранится как число чуть меньше 1.005. Для денег храните суммы в целых центах или форматируйте через Intl.NumberFormat.

String(n) работает и с null и undefined (давая "null" и "undefined"), тогда как n.toString() в режиме strict был бы ошибкой компиляции, раз значение может отсутствовать.

Краткая шпаргалка

ЗадачаКодТип результата
Строка в число, строгоNumber(s) или +snumber (может быть NaN)
Целое из начала текстаparseInt(s, 10)number (может быть NaN)
Дробное из начала текстаparseFloat(s)number (может быть NaN)
Проверить результатNumber.isFinite(n), Number.isNaN(n)boolean
Большое целоеBigInt(s)bigint
Число в строкуString(n), n.toString(), `${n}`string
Фиксированное число знаковn.toFixed(2)string
Другое основаниеn.toString(16)string
Разделители тысячn.toLocaleString("en-US")string

Часто задаваемые вопросы

Как преобразовать строку в число в TypeScript?

Используйте Number(text). Он возвращает number: значение для корректного числового текста, NaN для всего остального и 0 для пустой строки или строки из одних пробелов. Если в тексте могут быть символы в конце, например "42px", используйте parseInt(text, 10) или parseFloat(text).

Можно ли привести строку к числу через as number?

Нет. "42" as number даёт ошибку компиляции (TS2352), и даже если протолкнуть его через unknown, утверждение меняет только тип, который видит компилятор: во время выполнения значение остаётся строкой "42". Преобразуйте значение через Number(), parseInt() или parseFloat().

Чем Number() отличается от parseInt() в TypeScript?

Number преобразует всю строку целиком и возвращает NaN, если какая-то её часть не числовая, поэтому Number("42px") равно NaN. parseInt читает цифры с начала и останавливается на первой нецифре, поэтому parseInt("42px", 10) равно 42, а дробную часть он отбрасывает. Number("") равно 0, а parseInt("") равно NaN.

Как проверить, что строка является корректным числом?

Преобразуйте её и проверьте результат: const n = Number(text); if (text.trim() !== "" && Number.isFinite(n)) { ... }. Проверка на пустую строку важна, потому что Number("") равно 0. Используйте Number.isNaN, а не глобальный isNaN, который TypeScript и так принимает только с аргументом типа number.

Как преобразовать число в строку в TypeScript?

String(n), n.toString() и шаблонный литерал `${n}` дают одинаковый результат. Используйте n.toFixed(2) для фиксированного числа знаков после запятой, n.toString(16) для другой системы счисления и n.toLocaleString("en-US") для разделителей тысяч.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ