Avatar ·

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

Всем привет! Я только начал изучать TypeScript и столкнулся с такой проблемой. У меня есть функция, которая принимает строку, и мне нужно определить, содержит ли эта строка только цифры (то есть является ли она числовым представлением). Я пробовал использовать typeof, но он для строк всегда возвращает 'string'. Также пытался использовать Number() или parseInt(), но они ведут себя странно: например, Number("123abc") возвращает NaN, а parseInt("123abc") возвращает 123. Это не совсем то, что мне нужно. Вот пример кода, который я пытаюсь написать: ```typescript function isNumericString(value: string): boolean { // Как правильно проверить? return typeof value === 'number'; // Не работает, value всегда строка } // Примеры: console.log(isNumericString("123")); // Должно быть true console.log(isNumericString("12.5")); // Должно быть true console.log(isNumericString("abc")); // Должно быть false console.log(isNumericString("12abc")); // Должно быть false console.log(isNumericString("")); // Должно быть false ``` Подскажите, как это сделать правильно? Может быть, есть какая-то встроенная функция или лучшая практика для TypeScript? Буду благодарен за примеры кода и объяснение. <<>>

Проверка строки на числовое значение в TypeScript

Проблема, с которой вы столкнулись, очень распространена. В JavaScript (и TypeScript) нет встроенного метода, который бы идеально решал эту задачу, но есть несколько надёжных подходов. Рассмотрим лучшие из них.

Основное решение: использование Number() и isNaN()

Самый надёжный способ — это комбинация функций Number() и isNaN() (или Number.isNaN()). Вот как это работает:

function isNumericString(value: string): boolean {
  if (value === '' || value === null || value === undefined) {
    return false;
  }
  return !isNaN(Number(value));
}

Почему это работает?

  • Number(value) пытается преобразовать строку в число. Если строка содержит только цифры (с возможным знаком и десятичной точкой), она преобразуется успешно. Если нет — возвращает NaN.
  • isNaN() проверяет, является ли результат NaN. Если Number() вернул число — значит, строка числовая.
  • Дополнительная проверка на пустую строку важна, потому что Number('') возвращает 0, что может быть нежелательно.

Улучшенная версия с учётом пробелов

Иногда строки могут содержать пробелы в начале или конце. Чтобы это учесть, можно добавить trim():

function isNumericString(value: string): boolean {
  const trimmed = value.trim();
  if (trimmed === '') {
    return false;
  }
  return !isNaN(Number(trimmed));
}

// Примеры:
console.log(isNumericString("  123  ")); // true
console.log(isNumericString("   "));     // false
console.log(isNumericString("12.5"));    // true
console.log(isNumericString("12,5"));    // false (запятая не поддерживается)

Использование регулярного выражения (альтернатива)

Если вам нужно проверять только целые числа или числа в определённом формате, можно использовать регулярное выражение:

function isNumericString(value: string): boolean {
  return /^-?\d+(\.\d+)?$/.test(value.trim());
}

// Разбор регулярного выражения:
// ^ - начало строки
// -? - опциональный знак минуса
// \d+ - одна или более цифр
// (\.\d+)? - опциональная десятичная часть (точка и цифры)
// $ - конец строки

Важные замечания

  • Разница между isNaN и Number.isNaN: isNaN() сначала преобразует аргумент в число, а потом проверяет. Number.isNaN() не делает преобразования — он проверяет, является ли значение именно NaN (тип number). Для нашей задачи лучше использовать isNaN().
  • Научная нотация: Number('1e5') вернёт 100000, поэтому isNaN(Number('1e5')) вернёт false (то есть строка считается числовой). Если вам это не подходит, используйте регулярное выражение.
  • Пустая строка: Всегда проверяйте пустую строку отдельно, так как Number('') возвращает 0.

Рекомендация: Для большинства случаев используйте первый вариант с Number() и isNaN() — он наиболее универсален и понятен. Регулярное выражение стоит применять, когда нужен строгий контроль формата.

<<>>

Альтернативный подход: использование parseInt() и parseFloat()

Можно также использовать функции parseInt() и parseFloat(), но с дополнительной проверкой:

function isNumericString(value: string): boolean {
  const trimmed = value.trim();
  if (trimmed === '') return false;
  
  // Проверяем, что после разбора не осталось лишних символов
  const number = parseFloat(trimmed);
  return !isNaN(number) && number.toString() === trimmed;
}

// Примеры:
console.log(isNumericString("123"));   // true
console.log(isNumericString("12.5"));  // true
console.log(isNumericString("12abc")); // false (так как "12" !== "12abc")
console.log(isNumericString("abc"));   // false

Как это работает: parseFloat() извлекает число из начала строки, игнорируя последующие нечисловые символы. Затем мы сравниваем результат с исходной строкой — если они совпадают, значит, строка полностью является числом.

Плюсы: Не требует дополнительных проверок на пустую строку и хорошо обрабатывает случаи типа "123abc".

Минусы:

  • Не поддерживает научную нотацию (например, "1e5" вернёт false).
  • Может не работать с пробелами внутри числа (хотя мы используем trim()).
  • Для целых чисел лучше использовать parseInt() с указанием системы счисления.

Этот подход хорош, когда нужно строго проверить, что строка содержит только цифры и одну десятичную точку, без лишних символов.