Обновление версий YupResolver

Версионирование YupResolver напрямую связано с развитием пакета @hookform/resolvers и изменениями в архитектуре React Hook Form. Основная задача резолвера — адаптация схем валидации Yup к унифицированному интерфейсу резолверов, который ожидает библиотека форм. При обновлении версий важны три направления совместимости: API React Hook Form, версия Yup и внутренняя структура резолвера.


Архитектурная роль резолвера и влияние версий

YupResolver выступает адаптером между схемой Yup и механизмом валидации React Hook Form. Его задача — преобразовать результат работы schema.validate() в структуру:

  • values (валидные данные)
  • errors (структурированные ошибки)

Любое изменение в одной из зависимостей влияет на контракт:

  • изменения в Yup (валидация, кастомные ошибки, strict mode)
  • изменения в React Hook Form (формат resolver, контекст, mode)
  • изменения в @hookform/resolvers (обёртки для различных библиотек схем)

Совместимость Yup и YupResolver

На практике критические изменения чаще происходят при переходе между major-версиями Yup:

Yup v0.32 → v0.40+

  • усиление строгой типизации схем
  • изменение поведения required() и nullable()
  • корректировки в обработке mixed() типов

YupResolver при этом может:

  • по-разному интерпретировать ошибки ValidationError
  • изменять структуру inner ошибок

Изменения в React Hook Form resolver API

Существенный переход произошёл при стабилизации API resolver:

(schema) => async (values, context, options) => {
  return {
    values,
    errors
  }
}

В более старых версиях наблюдались различия:

  • отсутствие context
  • ограниченные options (например, mode-related параметры)
  • несовместимость с async validation chaining

Обновление YupResolver часто требует синхронизации с текущей сигнатурой:

  • добавление context для conditional schema
  • поддержка criteriaMode: "all"
  • корректная обработка shouldUseNativeValidation

Основные изменения в версиях @hookform/resolvers

Переход v1 → v2

  • унификация API всех резолверов (Yup, Zod, Joi)
  • переход на строгий TypeScript контракт
  • изменение структуры FieldError

Ключевой эффект для YupResolver:

  • ошибки начали возвращаться в нормализованном формате { type, message, ref }
  • уменьшилось количество ручной трансформации ошибок

Переход v2 → v3

Основные изменения:

  • оптимизация производительности резолвера
  • переход на более чистую async-модель
  • улучшение tree-shaking

Для YupResolver:

  • уменьшение накладных расходов при validateSync
  • переход на единый pipeline обработки ошибок
  • улучшение работы с nested schema (object().shape())

Переход v3 → v4

Ключевые изменения связаны с совместимостью React Hook Form v7:

  • изменение internal resolver context
  • усиление поддержки TypeScript generics
  • корректировка обработки defaultValues

В YupResolver:

  • обновление сигнатуры Resolver<T>
  • строгая типизация входных значений схемы
  • устранение неявных any в error mapping

Переход v4 → v5

Одна из наиболее заметных эволюций:

  • унификация поведения всех schema-resolvers
  • отказ от устаревших overload-ов
  • улучшение поддержки async validation chains

В YupResolver:

  • переработка обработки ValidationError.inner
  • более точное сопоставление ошибок по path
  • улучшение поддержки abortEarly: false

Изменения в обработке ошибок Yup

Yup возвращает ошибки через объект ValidationError, ключевые поля:

  • message
  • path
  • inner
  • type

С обновлением версий YupResolver изменялась стратегия преобразования:

Ранние версии

  • простое сопоставление path → message
  • игнорирование вложенных inner ошибок
  • потеря контекста массива ошибок

Современные версии

  • рекурсивная обработка inner
  • агрегация ошибок массивов (array fields)
  • поддержка criteriaMode: "all" в React Hook Form

Типизация TypeScript и влияние версий

Одним из ключевых аспектов обновления является типизация:

До v4

  • частичное использование generics
  • слабая типизация Resolver
  • необходимость ручного указания типов формы

После v4–v5

  • строгая типизация Resolver<TFieldValues>
  • вывод типов из Yup schema (ограниченно)
  • улучшенная интеграция с InferType из Yup

Типичный паттерн:

type FormValues = Yup.InferType<typeof schema>;

И его использование в резолвере:

useForm<FormValues>({
  resolver: yupResolver(schema)
});

Изменения поведения validateSync и validate

YupResolver использует либо:

  • validate (async)
  • validateSync (sync fallback)

С течением версий:

  • уменьшена зависимость от sync-валидации
  • улучшена работа с асинхронными кастомными тестами (test() с промисами)
  • устранены race-condition при повторной валидации

Миграционные изменения между версиями

При обновлении YupResolver основное внимание уделяется следующим зонам:

1. Сигнатура resolver

Изменения могут требовать:

  • обновления типов useForm
  • пересборки generics
  • проверки совместимости с mode: "onChange"

2. Обработка nested objects

Изменения в flattening стратегии:

  • раньше: частичная поддержка a.b.c
  • сейчас: полная рекурсивная нормализация

3. Массовые ошибки массивов

Старое поведение:

  • отображалась только первая ошибка массива

Новое поведение:

  • поддержка всех индексов
  • корректное сопоставление field[index]

Частые проблемы после обновления версий

Потеря ошибок вложенных схем

Причина:

  • изменение обработки ValidationError.inner

Решение:

  • убедиться в использовании abortEarly: false

Несовпадение типов TypeScript

Причина:

  • несовместимость старого Resolver<any> с новым generics API

Некорректная работа defaultValues

Причина:

  • изменение порядка инициализации resolver в React Hook Form v7+

Производительность и оптимизация

С каждым обновлением:

  • уменьшается количество пересозданий resolver-функции
  • оптимизируется кеширование схем Yup
  • улучшается работа с memoization в React Hook Form

Особенно важно:

  • повторное использование schema instance
  • избегание создания схемы внутри компонента

Влияние ESM/CJS переходов

Начиная с более поздних версий:

  • усиливается поддержка ESM
  • частичная депрекация CommonJS сборок
  • улучшение tree-shaking в bundler’ах (Vite, Webpack 5)

Изменения поведения conditional schemas

Сложные схемы:

yup.object({
  type: yup.string(),
  value: yup.mixed().when("type", {
    is: "number",
    then: yup.number(),
    otherwise: yup.string()
  })
})

В новых версиях YupResolver:

  • корректнее пересчитывается зависимость полей
  • уменьшаются ошибки stale validation context
  • улучшается реактивность conditional rules