Структура схемы валидации Yup

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

Схема является иммутабельным объектом: после создания она не изменяется, а все модификации возвращают новую версию схемы.


Основные типы схем

Yup предоставляет несколько базовых конструкторов схем, соответствующих примитивным типам JavaScript.

Строки

import * as Yup from 'yup';

const schema = Yup.string();

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

const schema = Yup.string()
  .min(3)
  .max(50)
  .required()
  .trim();

Ключевые методы:

  • min(n) — минимальная длина строки
  • max(n) — максимальная длина
  • required() — обязательное поле
  • trim() — автоматическое удаление пробелов по краям
  • email() — проверка email формата
  • matches(regex) — проверка по регулярному выражению

Числа

const schema = Yup.number();

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

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

Основные методы:

  • min(n) — минимальное значение
  • max(n) — максимальное значение
  • positive() — только положительные числа
  • negative() — только отрицательные числа
  • integer() — только целые числа
  • moreThan(n) / lessThan(n) — строгие границы

Булевы значения

const schema = Yup.boolean();
const schema = Yup.boolean().required();

Булева схема обычно используется для чекбоксов и флагов состояния.


Даты

const schema = Yup.date();
const schema = Yup.date()
  .min(new Date(2000, 0, 1))
  .max(new Date())
  .required();

Методы:

  • min(date) — минимальная дата
  • max(date) — максимальная дата
  • автоматическое приведение строк к Date

Объектные схемы

Объектные схемы являются ключевым элементом Yup, поскольку позволяют описывать структуру сложных данных.

const schema = Yup.object({
  name: Yup.string().required(),
  age: Yup.number().required(),
});

Альтернативный способ через shape:

const schema = Yup.object().shape({
  name: Yup.string().required(),
  age: Yup.number().required(),
});

Особенности объектной схемы

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

Вложенные объекты

const schema = Yup.object({
  user: Yup.object({
    name: Yup.string().required(),
    address: Yup.object({
      city: Yup.string().required(),
      zip: Yup.string().required(),
    }),
  }),
});

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


Массивы

Схемы массивов описывают коллекции однотипных элементов.

const schema = Yup.array()
  .of(Yup.string().required())
  .min(1)
  .max(10);

Метод .of() задаёт схему элементов массива.

Пример с объектами

const schema = Yup.array().of(
  Yup.object({
    id: Yup.number().required(),
    title: Yup.string().required(),
  })
);

Универсальный тип mixed

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

const schema = Yup.mixed();

Применяется для:

  • файлов
  • кастомных объектов
  • неопределённых структур
const schema = Yup.mixed()
  .required()
  .nullable();

Модификаторы схем

required / optional

Yup.string().required();
Yup.string().notRequired();

required() означает обязательное значение, notRequired() снимает обязательность.


nullable

Yup.string().nullable();

Позволяет значению быть null.


default

Yup.string().default('guest');

Устанавливает значение по умолчанию при отсутствии данных.


Приведение типов (casting)

Yup выполняет автоматическое приведение типов перед валидацией.

Пример:

  • строка "123" может быть преобразована в число 123
  • строка даты может быть преобразована в Date
Yup.number().cast("42"); // 42

Кастинг можно отключить:

schema.validate(data, { strict: true });

Референсы и связи между полями

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

const schema = Yup.object({
  password: Yup.string().required(),
  confirmPassword: Yup.string().oneOf([Yup.ref('password')]),
});

Yup.ref() создаёт зависимость между значениями внутри одной схемы.


Условная валидация

Условные правила реализуются через when().

const schema = Yup.object({
  isCompany: Yup.boolean(),
  companyName: Yup.string().when('isCompany', {
    is: true,
    then: schema => schema.required(),
    otherwise: schema => schema.notRequired(),
  }),
});

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


Трансформации значений

Метод transform() позволяет изменять входные данные до проверки.

Yup.string().transform(value => value?.trim());

Пример с числом:

Yup.number().transform(value => {
  return isNaN(value) ? undefined : value;
});

Порядок выполнения правил

Валидация в Yup происходит в определённой последовательности:

  1. Приведение типов (casting)
  2. Трансформации (transform)
  3. Проверка required
  4. Остальные ограничения (min, max, matches и т.д.)
  5. Кастомные тесты (test)
Yup.string().test('custom-rule', 'Ошибка', value => {
  return value === 'ok';
});

Частичная и строгая валидация

strict mode

schema.validate(data, { strict: true });

Отключает приведение типов и выполняет проверку «как есть».


partial validation

schema.validateAt('user.name', data);

Позволяет валидировать отдельное поле внутри сложной структуры.


Кастомные тесты

Метод test() добавляет пользовательскую логику проверки.

Yup.string().test(
  'no-spaces',
  'Строка не должна содержать пробелы',
  value => !/\s/.test(value)
);

Функция теста получает:

  • value — текущее значение
  • context — контекст выполнения

Композиция схем

Схемы можно переиспользовать и комбинировать.

const baseString = Yup.string().min(3).max(20);

const nameSchema = baseString.required();
const nicknameSchema = baseString.notRequired();

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