Диапазоны значений

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


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

min и max

Базовые ограничения диапазона задаются через min() и max():

import * as Yup from 'yup';

const schema = Yup.object({
  age: Yup.number()
    .min(18, 'Минимальный возраст — 18 лет')
    .max(65, 'Максимальный возраст — 65 лет')
});

Особенности поведения:

  • min() включает граничное значение (>=)
  • max() также включает граничное значение (<=)
  • при нарушении условий возвращается сообщение ошибки

strict диапазоны

Иногда требуется исключить границы. Для этого используются комбинации:

Yup.number()
  .moreThan(0)   // строго больше 0
  .lessThan(100) // строго меньше 100

Таким образом можно задавать интервалы вида (0, 100) вместо [0, 100].

Положительные и отрицательные диапазоны

Дополнительные ограничения:

Yup.number().positive(); // > 0
Yup.number().negative(); // < 0
Yup.number().nonNegative(); // >= 0
Yup.number().nonPositive(); // <= 0

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


Строковые диапазоны

Для строк диапазон трактуется как ограничение длины.

min и max длины

const schema = Yup.object({
  username: Yup.string()
    .min(3, 'Минимум 3 символа')
    .max(20, 'Максимум 20 символов')
});

Здесь диапазон относится к количеству символов.

trim и влияние на диапазон

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

Yup.string()
  .trim()
  .min(3)

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


Диапазоны дат

Работа с датами предполагает использование хронологических границ.

const schema = Yup.object({
  startDate: Yup.date()
    .min(new Date(2020, 0, 1), 'Дата слишком ранняя')
    .max(new Date(2030, 0, 1), 'Дата слишком поздняя')
});

Сравнение дат

Дополнительно применяются методы:

  • min() — не раньше указанной даты
  • max() — не позже указанной даты

Относительные диапазоны

Часто диапазоны вычисляются динамически:

const today = new Date();

Yup.date()
  .min(today, 'Дата не может быть в прошлом')

Диапазоны массивов

Для массивов диапазон задаёт допустимое количество элементов.

min и max элементов

const schema = Yup.object({
  tags: Yup.array()
    .min(1, 'Добавьте хотя бы один элемент')
    .max(5, 'Не более 5 элементов')
});

Фиксированная длина

Если требуется строгое количество элементов:

Yup.array().length(3, 'Должно быть ровно 3 элемента')

Вложенные диапазоны и составные структуры

Диапазоны могут комбинироваться внутри объектов.

const schema = Yup.object({
  user: Yup.object({
    age: Yup.number().min(18).max(60),
    name: Yup.string().min(2).max(50),
    roles: Yup.array().min(1).max(3)
  })
});

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


Условные диапазоны

Диапазоны могут зависеть от других полей.

const schema = Yup.object({
  password: Yup.string().min(8),
  confirmPassword: Yup.string().when('password', (password, schema) =>
    password
      ? schema.min(password.length)
      : schema
  )
});

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


Использование refs в диапазонах

Ссылки позволяют строить зависимые ограничения:

const schema = Yup.object({
  minValue: Yup.number(),
  maxValue: Yup.number()
    .min(Yup.ref('minValue'), 'max должен быть >= min')
});

Это обеспечивает согласованность диапазонов между полями.


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

Когда стандартных методов недостаточно, применяется test():

Yup.number().test(
  'custom-range',
  'Значение вне допустимого диапазона',
  function (value) {
    return value >= 10 && value <= 20;
  }
);

Это даёт полный контроль над логикой проверки.


Нормализация значений перед проверкой диапазона

Диапазоны часто зависят от преобразования данных:

Yup.number()
  .transform((value, originalValue) =>
    typeof originalValue === 'string' ? parseInt(originalValue, 10) : value
  )
  .min(0)
  .max(100)

Без корректной трансформации диапазон может работать некорректно.


Ошибки при работе с диапазонами

На практике часто встречаются следующие проблемы:

  • сравнение строк вместо чисел из-за отсутствия трансформации
  • некорректные даты из-за строкового формата
  • конфликтующие условия min и max
  • зависимые поля без проверки наличия значений

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


Композиция диапазонов

Диапазоны можно комбинировать с другими валидаторами:

Yup.number()
  .required()
  .integer()
  .min(1)
  .max(1000)

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