Режимы валидации: strict и coercion

Библиотека Yup строится вокруг двух ключевых принципов обработки входных данных: валидация и приведение типов (casting / coercion). Понимание различий между строгим режимом и режимом приведения типов критично для предсказуемого поведения схем, особенно в формах, API и слоях обработки пользовательского ввода.


Базовая модель обработки данных в Yup

Перед тем как разбирать режимы, важно понимать внутренний цикл работы схемы:

  1. Входное значение поступает в схему
  2. Применяется приведение типов (cast)
  3. Выполняются трансформации (transform)
  4. Проверяются правила валидации (required, min, matches и т.д.)
  5. Возвращается либо нормализованное значение, либо ошибка

Ключевой момент: Yup по умолчанию не просто проверяет, но и изменяет данные.


Coercion (приведение типов) — поведение по умолчанию

Coercion — это автоматическое преобразование входных данных к ожидаемому типу схемы.

Примеры поведения coercion

Строка → число

import * as Yup from "yup";

const schema = Yup.number();

schema.validateSync("42"); 
// 42 (number)

Здесь строка "42" автоматически преобразуется в число 42.


Пустая строка → null / NaN

schema.validateSync(""); 
// NaN

Пустые значения часто приводятся к невалидным числам или undefined, в зависимости от схемы.


Boolean coercion

const schema = Yup.boolean();

schema.validateSync("true");  // true
schema.validateSync("false"); // false
schema.validateSync("1");     // true

Входные строковые значения интерпретируются как логические.


Особенности coercion

  • Работает автоматически
  • Применяется до валидации
  • Зависит от типа схемы
  • Может неожиданно изменять данные
  • Упрощает работу с HTML-формами

Strict mode — отключение приведения типов

Strict mode полностью отключает автоматическое преобразование значений.

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

schema.validateSync("42");
// ValidationError

Здесь строка "42" не будет преобразована в число, а сразу вызовет ошибку.


Поведение strict mode

При strict(true):

  • отключается casting
  • отключаются автоматические преобразования типов
  • значение проходит валидацию “как есть”
  • трансформации (transform) могут сохраняться, но без coercion логики типа

Сравнение strict и coercion

Числовая схема

const loose = Yup.number();
const strict = Yup.number().strict(true);

Loose (coercion включён)

loose.validateSync("10"); 
// 10

Strict

strict.validateSync("10"); 
// Error

Булевый тип

const schema = Yup.boolean().strict(true);

schema.validateSync("true");
// Error

Когда coercion полезен

Coercion особенно важен в следующих сценариях:

HTML-формы

Поля формы всегда приходят как строки:

<input type="number" />

Фактическое значение:

"123"

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


Быстрая нормализация данных

API может присылать несогласованные типы:

{
  "age": "25"
}

Coercion приводит данные к нужному виду без ручной обработки.


Интеграция с form-библиотеками

В связке с React Hook Form или Formik coercion снижает количество преобразований на уровне UI.


Когда strict mode необходим

Strict mode используется, когда важна жёсткая типизация входных данных.

API с гарантированным контрактом

Если сервис ожидает строго типизированный JSON:

const schema = Yup.object({
  id: Yup.number().strict(true)
});

Строковое "1" будет считаться ошибкой.


Безопасные доменные модели

Когда важно исключить неявные преобразования:

  • финансовые системы
  • расчёты
  • идентификаторы
  • критические бизнес-правила

Защита от неявных ошибок

Coercion может скрывать ошибки:

Yup.number().validateSync("abc"); 
// NaN (иногда проходит дальше)

Strict mode предотвращает такие ситуации.


Комбинирование strict и transform

Strict mode не отменяет возможность трансформаций:

const schema = Yup.string()
  .strict(true)
  .transform((value) => value.trim());

Здесь:

  • coercion отключён
  • но ручная трансформация сохраняется

Влияние на validate vs cast

Yup имеет два уровня работы:

  • cast() — приводит типы
  • validate() — проверяет и при необходимости тоже кастит

В coercion режиме

schema.cast("42"); // 42

В strict режиме

schema.cast("42"); // "42"

Cast перестаёт изменять тип данных.


Поведение с undefined и null

Coercion

Yup.number().validateSync(undefined);
// undefined проходит или становится NaN в зависимости от схемы

Strict

Yup.number().strict(true).validateSync(undefined);
// чаще всего ошибка required (если не optional)

Optional поля и strict

Strict mode не отменяет optional():

Yup.number()
  .strict(true)
  .optional();
  • undefined допустим
  • "123" всё равно не будет преобразован

Частые ошибки при использовании режимов

Ошибка 1: ожидание автоматического преобразования

Yup.number().strict(true).validateSync("10");

Ожидание: 10 Факт: ошибка


Ошибка 2: смешивание API-данных и strict схем

Внешние API часто возвращают строки вместо чисел. Strict schema ломает интеграцию.


Ошибка 3: непонимание cast

schema.cast(value)

Может вести себя иначе в strict и non-strict режимах, что приводит к несоответствиям между UI и backend.


Практическая стратегия выбора режима

Coercion подходит, если:

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

Strict mode подходит, если:

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

Поведение внутри объектных схем

const schema = Yup.object({
  age: Yup.number(),
  active: Yup.boolean()
});

В coercion режиме:

schema.validateSync({
  age: "30",
  active: "true"
});

Результат:

{
  age: 30,
  active: true
}

В strict режиме:

Yup.object({
  age: Yup.number().strict(true),
  active: Yup.boolean().strict(true)
});

Те же данные вызовут ошибку валидации.


Итоговая модель поведения

  • coercion = гибкая нормализация входных данных
  • strict = строгая проверка без преобразований
  • оба режима влияют на validate и cast
  • выбор режима определяет архитектуру обработки данных

Работа с этими режимами напрямую определяет предсказуемость схем и уровень контроля над входящими значениями в приложении.