Yup валидация

Yup — это мощная библиотека для построения схем валидации данных в JavaScript и TypeScript. Она предоставляет декларативный способ проверки значений форм, объектов или любых структур данных, обеспечивая строгую типизацию и удобное управление ошибками. Основной концепцией является схема, которая описывает требования к данным и правила их проверки.

Создание базовой схемы

Схема создаётся с помощью конструктора yup.object() для объектов, yup.string(), yup.number() и других типов данных. Например:

import * as yup from 'yup';

const schema = yup.object({
  name: yup.string().required('Имя обязательно'),
  age: yup.number().min(18, 'Возраст должен быть не менее 18').required(),
  email: yup.string().email('Неверный формат email').required(),
});
  • yup.string(), yup.number() — создают базовые типы данных.
  • .required() — обязательное поле.
  • .min(), .max(), .email() — встроенные методы проверки значений.
  • Сообщение об ошибке можно передавать как аргумент метода.

Валидация данных

Для проверки объекта используется метод validate или validateSync для синхронной валидации:

const data = { name: 'Иван', age: 25, email: 'ivan@mail.com' };

schema.validate(data)
  .then(valid => {
    console.log('Данные корректны', valid);
  })
  .catch(err => {
    console.log('Ошибка валидации:', err.errors);
  });
  • validate возвращает Promise, что удобно для асинхронной работы с формами.
  • validateSync выбрасывает исключение сразу, что удобно для простых сценариев.

Вложенные объекты и массивы

Yup позволяет создавать схемы для вложенных структур данных:

const schema = yup.object({
  user: yup.object({
    name: yup.string().required(),
    email: yup.string().email(),
  }),
  tags: yup.array().of(yup.string().min(2)).required(),
});
  • yup.object({...}) описывает вложенный объект.
  • yup.array().of(schema) описывает массив, элементы которого проходят валидацию по указанной схеме.

Кастомные проверки

Yup поддерживает кастомные тесты, что позволяет создавать сложные условия:

const schema = yup.string().test(
  'starts-with-A',
  'Должно начинаться с буквы A',
  value => value && value.startsWith('A')
);
  • Первый аргумент — уникальный идентификатор теста.
  • Второй — сообщение об ошибке.
  • Третий — функция проверки, возвращает true или false.

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

Валидация может зависеть от других полей с помощью .when:

const schema = yup.object({
  password: yup.string().required(),
  confirmPassword: yup.string().when('password', {
    is: val => val && val.length > 0,
    then: yup.string().oneOf([yup.ref('password')], 'Пароли должны совпадать'),
  }),
});
  • yup.ref('password') ссылается на значение другого поля.
  • .oneOf([...], 'сообщение') проверяет соответствие одному из допустимых значений.

Асинхронная валидация

Yup позволяет выполнять проверки с асинхронными операциями, например, проверка уникальности email через API:

const schema = yup.string().test(
  'unique-email',
  'Email уже занят',
  async value => {
    const response = await fetch(`/api/check-email?email=${value}`);
    const result = await response.json();
    return result.isAvailable;
  }
);
  • Метод validate корректно обрабатывает асинхронные тесты.
  • Использование async/await позволяет интегрировать проверки с внешними источниками данных.

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

Схемы можно комбинировать, наследовать и расширять:

const baseUserSchema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
});

const extendedUserSchema = baseUserSchema.shape({
  age: yup.number().min(18),
  role: yup.string().oneOf(['admin', 'user']),
});
  • Метод .shape({...}) добавляет или переопределяет поля базовой схемы.
  • Позволяет создавать модульные и переиспользуемые структуры валидации.

Настройка сообщений об ошибках

Yup позволяет глобально настроить сообщения через setLocale:

yup.setLocale({
  mixed: {
    required: 'Это поле обязательно',
  },
  string: {
    email: 'Некорректный email',
  },
  number: {
    min: 'Минимальное значение ${min}',
  },
});
  • ${min}, ${max}, ${value} — placeholders для динамических значений.
  • Позволяет локализовать ошибки и унифицировать стиль сообщений.

Интеграция с формами

Yup хорошо сочетается с библиотеками управления формами, например Formik или React Hook Form, предоставляя декларативное описание валидации и удобный API для обработки ошибок.

import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';

const { register, handleSubmit, formState: { errors } } = useForm({
  resolver: yupResolver(schema),
});
  • yupResolver превращает схему Yup в функцию, понятную форме.
  • Поля errors содержат все сообщения о некорректных данных.

Преимущества Yup

  • Декларативная структура валидации.
  • Поддержка вложенных объектов и массивов.
  • Асинхронные и условные проверки.
  • Лёгкая интеграция с популярными библиотеками форм.
  • Возможность глобальной настройки сообщений и локализации.

Yup обеспечивает гибкий и мощный механизм проверки данных, делая валидацию форм и объектов безопасной, предсказуемой и масштабируемой.