Синхронная валидация через validateSync

Метод validateSync в Yup выполняет синхронную проверку данных относительно заданной схемы. Его ключевая особенность заключается в том, что он не возвращает Promise и не требует использования async/await. Валидация происходит немедленно, в рамках текущего стека вызовов, а результат либо возвращается сразу, либо выбрасывается исключение при нарушении правил схемы.

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

Основная идея:

  • входные данные проходят проверку по схеме;
  • при успешной валидации возвращается преобразованное значение;
  • при ошибке выбрасывается исключение ValidationError.

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

Сигнатура метода validateSync

Метод вызывается непосредственно у схемы:

schema.validateSync(value, options?)

Где:

  • value — данные, которые необходимо проверить;
  • options — объект конфигурации поведения валидации.

Возвращаемое значение:

  • преобразованные и проверенные данные при успехе;
  • исключение ValidationError при несоответствии схемы.

Простая синхронная схема

import * as Yup from 'yup';

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

const result = schema.validateSync('hello');

В этом примере:

  • строка проходит проверку на обязательность;
  • затем проверяется минимальная длина;
  • результатом становится исходная строка, если она соответствует условиям.

При передаче некорректного значения:

schema.validateSync('');

будет выброшена ошибка, содержащая информацию о первом нарушенном ограничении.

Обработка ошибок validateSync

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

try {
  schema.validateSync('ab');
} catch (err) {
  console.log(err.name); // ValidationError
  console.log(err.message); // описание ошибки
}

Полезные свойства ошибки:

  • message — текстовое описание;
  • path — путь до поля, где произошла ошибка;
  • errors — массив сообщений (в случае нескольких нарушений).

Использование объектов

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

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

const user = {
  name: 'Alex',
  age: 25
};

const validated = userSchema.validateSync(user);

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

Поведение abortEarly

Опция abortEarly управляет тем, останавливается ли валидация после первой ошибки.

userSchema.validateSync(user, { abortEarly: false });

Поведение:

  • true (по умолчанию) — проверка прекращается при первой ошибке;
  • false — собираются все ошибки по всем полям.

При abortEarly: false массив errors внутри исключения содержит все найденные нарушения.

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

Yup поддерживает проверку массивов через array().of().

const schema = Yup.array().of(
  Yup.number().positive().integer()
);

schema.validateSync([1, 2, 3]);

Если хотя бы один элемент нарушает правило:

schema.validateSync([1, -2, 3]);

будет выброшена ошибка, указывающая на индекс проблемного элемента.

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

Перед валидацией Yup может приводить значение к нужному типу.

const schema = Yup.number();

schema.validateSync('42'); // вернёт 42 как число

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

Опция strict

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

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

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

Теперь значение должно строго соответствовать ожидаемому типу.

Вложенные структуры

Синхронная валидация корректно работает с вложенными объектами любой глубины.

const schema = Yup.object({
  profile: Yup.object({
    username: Yup.string().required(),
    stats: Yup.object({
      score: Yup.number().min(0)
    })
  })
});

schema.validateSync({
  profile: {
    username: 'user1',
    stats: {
      score: 10
    }
  }
});

При ошибке путь будет отражать вложенность, например:

profile.stats.score

Отличие от validate

validateSync отличается от validate фундаментально:

  • validateSync — синхронный, выбрасывает исключение;
  • validate — асинхронный, возвращает Promise.

Пример асинхронного аналога:

await schema.validate(value);

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

Ограничения синхронной валидации

Синхронный режим не поддерживает:

  • запросы к серверу;
  • асинхронные кастомные тесты (test с Promise);
  • задержанные вычисления.

При попытке использовать асинхронные проверки validateSync либо игнорирует их, либо приводит к ошибке конфигурации схемы.

Комбинация с transform

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

const schema = Yup.number().transform((value) => {
  return Number(value);
});

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

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

Практическая модель поведения validateSync

При вызове метода происходит последовательность шагов:

  1. Приведение типов (если не strict);
  2. Применение трансформаций;
  3. Проверка обязательных ограничений;
  4. Последовательное выполнение правил схемы;
  5. Генерация результата или ошибки.

Такой порядок обеспечивает детерминированность поведения при каждом вызове.

Использование в прикладных сценариях

Синхронная валидация применяется в случаях:

  • проверка форм до отправки;
  • валидация конфигурационных объектов;
  • проверка данных в чистых функциях;
  • обработка входных параметров библиотек.

Её основное преимущество — отсутствие асинхронного оверхеда и мгновенное получение результата, что делает validateSync удобным инструментом для локальных проверок данных внутри приложения.