В библиотеке Joi работа с числами строится вокруг базового типа
number(), который охватывает как целые, так и дробные
значения. Поведение схемы определяется набором цепочных методов,
позволяющих уточнять допустимые диапазоны, точность и дополнительные
ограничения.
Основой для любой числовой валидации служит
Joi.number():
const schema = Joi.number();
Такое определение допускает любые числовые значения, включая целые и
дробные. На уровне JavaScript значения проверяются через
typeof value === 'number', при этом NaN по умолчанию
считается недопустимым.
Типичная схема расширяется ограничениями:
const schema = Joi.number().min(0).max(100);
Здесь задаётся диапазон допустимых значений от 0 до 100 включительно.
Метод integer() ограничивает входные данные только
целыми числами:
const schema = Joi.number().integer();
Допустимыми считаются:
Недопустимыми:
Внутренне проверка основывается на делении числа без остатка. Любое значение с дробной частью отклоняется.
Комбинирование с диапазонами часто используется для идентификаторов и счётчиков:
const schema = Joi.number().integer().min(1);
Такой вариант часто применяется для ID, где отрицательные значения и ноль недопустимы.
Joi не выделяет отдельного типа для float, однако поддерживает работу
с дробными значениями через precision().
const schema = Joi.number().precision(2);
Этот метод ограничивает количество знаков после запятой. Например:
Важно учитывать, что проверка точности происходит после преобразования числа в стандарт IEEE 754, поэтому возможны особенности с представлением дробей:
0.1 + 0.2 // 0.30000000000000004
Схема с precision() будет оценивать фактическое
представление числа, а не математическую абстракцию.
Ограничение диапазона значений задаётся методами min() и
max():
const schema = Joi.number().min(10).max(20);
Поведение строгое:
Комбинация с integer() позволяет формировать строгие
диапазоны для счётчиков, страниц, индексов:
const schema = Joi.number().integer().min(0).max(1000);
Метод multiple() проверяет, кратно ли число заданному
значению:
const schema = Joi.number().multiple(5);
Допустимые значения:
Недопустимые:
Механика основана на остатке от деления. Для дробных чисел поведение зависит от точности представления, поэтому в прикладных сценариях кратность чаще применяется к целым числам.
По умолчанию Joi может преобразовывать строки в числа при включённой
опции convert:
const schema = Joi.number();
schema.validate("42");
Строка "42" будет приведена к числу 42.
Однако поведение становится менее предсказуемым при некорректных значениях:
"42abc" → ошибка"" → ошибка" 42 " → допустимо (после trim и parse)Явное управление преобразованием:
const schema = Joi.number().strict();
В строгом режиме любые нечисловые типы отклоняются без попыток приведения.
Числовая модель JavaScript включает специальные значения
NaN, Infinity, -Infinity. В Joi
они по умолчанию считаются недопустимыми:
Joi.number().validate(NaN); // ошибка
Joi.number().validate(Infinity); // ошибка
Для изменения поведения используется:
const schema = Joi.number().allow('Infinity');
Но такие случаи встречаются редко и обычно требуют явной бизнес-логики.
Отрицательные значения регулируются теми же ограничениями:
const schema = Joi.number().min(-100).max(-1);
При отсутствии min() отрицательные числа допустимы по
умолчанию:
Joi.number().validate(-5); // допустимо
Одновременное использование integer() и
precision() не имеет практического смысла, так как целое
число не допускает дробной части:
Joi.number().integer().precision(2)
В подобных случаях precision() игнорируется логически,
хотя формально может присутствовать в цепочке вызовов.
В реальных API часто встречаются числовые значения в виде строк. Joi обрабатывает их при стандартной конфигурации:
const schema = Joi.number();
schema.validate("100");
Преобразование возможно, если строка строго соответствует числовому формату.
Для полного контроля используется:
Joi.number().strict()
const idSchema = Joi.number().integer().min(1).required();
const priceSchema = Joi.number().precision(2).min(0);
const pageSchema = Joi.number().integer().min(0);
const limitSchema = Joi.number().integer().min(1).max(100);
const percentSchema = Joi.number().min(0).max(100);
Ошибки в числовой валидации формируются с указанием типа нарушения:
number.base — значение не является числомnumber.min — меньше допустимого минимумаnumber.max — превышает максимумnumber.integer — не является целым числомnumber.precision — превышена точностьnumber.multiple — не кратно заданному значениюСтруктура ошибок позволяет точно определять причину отклонения без дополнительной обработки входных данных.