Целые числа: integer

Валидация целых чисел в Yup реализуется через числовую схему, основанную на Yup.number(), с дополнительным ограничением .integer(), которое проверяет, является ли значение целым числом без дробной части. Эта проверка работает поверх базовой числовой валидации и применяется после приведения типа и базовых проверок на корректность значения.

Основной механизм .integer()

Метод .integer() добавляет правило, которое проверяет, что число не содержит дробной части. Внутренне используется эквивалент проверки Number.isInteger(value) после приведения значения к числу.

import * as Yup from 'yup';

const schema = Yup.object({
  age: Yup.number().integer()
});

В данной схеме допустимыми значениями будут:

  • 0
  • 42
  • -7

Недопустимыми считаются:

  • 3.14
  • -0.5
  • NaN
  • строковые значения, не приводимые к числу

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

Если передано дробное число, валидатор возвращает ошибку с сообщением по умолчанию:

const schema = Yup.number().integer();

schema.validateSync(10.5);
// ValidationError: age must be an integer

Сообщение может быть переопределено через параметр:

Yup.number().integer('Значение должно быть целым числом');

Взаимодействие с преобразованием типов

Yup выполняет приведение типов перед проверками. Строки, содержащие числовое значение, преобразуются в число:

const schema = Yup.number().integer();

schema.validateSync('15'); // 15

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

schema.validateSync('15.2');
// ValidationError

Если строка не может быть преобразована в число, результатом будет NaN, что также считается невалидным значением.

Строгий режим (strict)

При включённом строгом режиме автоматическое преобразование отключается:

const schema = Yup.number()
  .strict()
  .integer();

Теперь строковые значения не будут преобразованы:

schema.validateSync('10'); // ошибка

Это важно при работе с уже нормализованными данными, где требуется жёсткий контроль типов.

Комбинация с обязательностью значения

Метод .integer() часто используется вместе с .required(), чтобы гарантировать наличие корректного целого числа:

const schema = Yup.object({
  count: Yup.number()
    .integer()
    .required('Поле обязательно')
});

В этом случае:

  • отсутствие значения → ошибка required
  • дробное число → ошибка integer
  • корректное целое число → проходит валидацию

Ограничения диапазона и целочисленная проверка

.integer() не заменяет ограничения диапазона. Проверка диапазона выполняется отдельно:

const schema = Yup.number()
  .integer()
  .min(1)
  .max(100);

Здесь валидируются одновременно:

  • целочисленность
  • минимальное значение
  • максимальное значение

Поведение с NaN и Infinity

Значения NaN, Infinity, -Infinity не проходят проверку числа и автоматически отклоняются до применения .integer():

Yup.number().integer().isValidSync(NaN); // false
Yup.number().integer().isValidSync(Infinity); // false

Пользовательская логика через .test()

При необходимости более сложной логики используется .test(), расширяющий стандартную проверку целых чисел:

const schema = Yup.number()
  .test(
    'is-strict-integer',
    'Допустимы только целые числа без исключений',
    value => Number.isInteger(value)
  );

Такой подход позволяет добавлять дополнительные условия, например:

  • проверку на чётность
  • проверку диапазона с нестандартными правилами
  • исключение определённых значений

Влияние nullable() и transform()

При использовании .nullable() значение null допускается отдельно от числовой проверки:

Yup.number().integer().nullable();

Значение null не обрабатывается как число и не проходит .integer(), но считается допустимым.

transform() может изменять входные данные перед проверкой:

const schema = Yup.number()
  .transform((value, originalValue) => {
    return originalValue === '' ? undefined : value;
  })
  .integer();

Это позволяет корректно обрабатывать пустые строки как отсутствие значения.

Особенности внутренней проверки

Проверка .integer() в Yup опирается на строгую числовую модель JavaScript. Из-за особенностей IEEE 754 возможны редкие пограничные случаи:

  • 1.0000000000000001 может интерпретироваться как 1
  • очень большие числа могут терять точность

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

Сочетание с другими методами number()

Схема числа в Yup может включать множество дополнительных ограничений:

Yup.number()
  .integer()
  .positive()
  .lessThan(1000)
  .required();

Здесь формируется строгая модель допустимых значений:

  • только целые числа
  • только положительные
  • меньше 1000
  • обязательное наличие значения

Такой подход используется при описании моделей данных, где критична точность типа значения, например:

  • индексы массивов
  • количество элементов
  • идентификаторы
  • счётчики
  • лимиты и квоты