Валидация диапазонов чисел

Диапазонная валидация числовых значений в Validator.js строится на основе функций проверки целых и вещественных чисел с параметрами границ, а также на комбинации преобразования типов и дополнительной логики для строгого контроля входных данных. Библиотека не предоставляет отдельной функции «range», однако поддерживает все необходимые механизмы через isInt, isFloat и вспомогательные опции.

В JavaScript входные данные часто поступают в виде строк, даже если по смыслу они являются числами. Validator.js работает преимущественно со строковыми значениями, поэтому диапазонная проверка почти всегда начинается с интерпретации строки как числа.

Ключевая идея диапазонной валидации заключается в проверке двух условий:

  • значение является числом корректного формата;
  • значение находится между заданными границами.

Целые числа и границы (isInt)

Основной инструмент для проверки целых чисел — validator.isInt().

Функция поддерживает параметры min и max, позволяющие задавать допустимый диапазон:

const validator = require('validator');

validator.isInt('10', { min: 5, max: 20 }); // true
validator.isInt('3', { min: 5, max: 20 });  // false
validator.isInt('25', { min: 5, max: 20 }); // false

Внутренняя логика выполняет:

  • проверку, что строка содержит допустимое целое число;
  • сравнение с минимальным значением;
  • сравнение с максимальным значением.

Дополнительно поддерживаются строгие режимы, включая запрет ведущих нулей и контроль знаков.

validator.isInt('05', { allow_leading_zeroes: false }); // false
validator.isInt('-10', { min: -20, max: 0 });           // true

Границы по умолчанию включаются в диапазон, то есть проверка является инклюзивной.

Вещественные числа (isFloat)

Для диапазонов с дробными значениями используется validator.isFloat().

validator.isFloat('10.5', { min: 5, max: 20 }); // true
validator.isFloat('4.99', { min: 5, max: 20 });  // false

Поддерживаются те же параметры:

  • min — нижняя граница;
  • max — верхняя граница;
  • дополнительные опции формата числа.

Пример с отрицательными значениями:

validator.isFloat('-3.14', { min: -10, max: 0 }); // true

Особенность isFloat заключается в том, что оно допускает научную нотацию:

validator.isFloat('1e3', { min: 500, max: 2000 }); // true

Приведение строк к числам

Validator.js не выполняет автоматическое преобразование в числовой тип. Это означает, что входные данные вида " 10 " или "10px" будут обрабатываться строго по правилам парсинга числа.

Примеры поведения:

validator.isInt('10');     // true
validator.isInt(' 10 ');   // true
validator.isInt('10px');   // false

Для более строгой обработки часто требуется предварительная нормализация:

const value = ' 42 ';
const normalized = value.trim();

validator.isInt(normalized, { min: 0, max: 100 });

Обработка крайних случаев

Диапазонная валидация должна учитывать нестандартные значения:

Пустые строки

validator.isInt('', { min: 1, max: 10 }); // false

NaN и Infinity

validator.isFloat('NaN');       // false
validator.isFloat('Infinity');   // false
validator.isFloat('-Infinity');  // false

Validator.js строго отклоняет такие значения, что упрощает защиту от некорректных вычислений.

Инклюзивные и эксклюзивные границы

По умолчанию диапазон включает границы (min <= value <= max). Для более строгих условий используются дополнительные проверки.

Пример реализации исключающей верхней границы:

const value = 10;

validator.isInt(value.toString(), { min: 0, max: 10 }) && value < 10;

Исключающая нижняя граница:

value > 0 && validator.isInt(value.toString(), { min: 0, max: 10 });

Подобный подход применяется при необходимости точного контроля математических интервалов.

Пользовательские валидаторы диапазона

При сложных условиях создаётся обёртка над стандартными функциями:

function isInRange(value, min, max) {
  if (!validator.isNumeric(value)) {
    return false;
  }

  const num = Number(value);
  return num >= min && num <= max;
}

Такой подход позволяет:

  • объединять целые и дробные проверки;
  • работать с предварительно преобразованными значениями;
  • расширять логику (например, добавлять шаг, округление, бизнес-ограничения).

Расширенная версия с проверкой целых чисел:

function isStrictIntRange(value, min, max) {
  return validator.isInt(value.toString(), { min, max }) &&
         Number.isInteger(Number(value));
}

Сочетание с нормализацией данных

Диапазонная проверка часто используется совместно с нормализацией входных данных:

function parseAndValidate(value) {
  const cleaned = value.replace(/\s+/g, '');

  if (!validator.isFloat(cleaned)) {
    return false;
  }

  const num = parseFloat(cleaned);
  return num >= 0 && num <= 100;
}

Подобная схема снижает риск ошибок, связанных с форматированием входных данных.

Типичные ошибки при диапазонной проверке

Одной из распространённых проблем является сравнение строк вместо чисел:

'100' < '20' // true (лексикографическое сравнение)

Validator.js предотвращает подобные ошибки, поскольку выполняет числовой парсинг перед сравнением границ.

Ещё одна проблема — отсутствие явного ограничения типа числа:

validator.isInt('10.5', { min: 0, max: 20 }); // false

Здесь дробная часть приводит к отклонению значения, что часто требует замены на isFloat.

Поведение при пограничных значениях

Пограничные случаи имеют особое значение при работе с диапазонами:

validator.isInt('5', { min: 5, max: 10 });  // true
validator.isInt('10', { min: 5, max: 10 }); // true

Такая модель важна для задач, связанных с индексами, рейтингами, процентами и лимитами.

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

Совместное использование с isNumeric

Функция isNumeric применяется для предварительной проверки перед диапазонной логикой:

if (validator.isNumeric(value)) {
  const num = Number(value);
  if (num >= 10 && num <= 50) {
    // значение в диапазоне
  }
}

Этот подход полезен при работе с нестрогими входными данными, где допустимы разные числовые форматы.

Практическая структура диапазонной валидации

Типовая схема проверки включает три этапа:

  1. проверка числового формата (isInt, isFloat, isNumeric);
  2. приведение к числу;
  3. сравнение с границами диапазона.
function validateRange(value, min, max) {
  if (!validator.isFloat(value.toString())) {
    return false;
  }

  const num = Number(value);
  return num >= min && num <= max;
}

Такая структура обеспечивает предсказуемость поведения и исключает неоднозначные интерпретации входных данных.