Библиотека Yup строится вокруг двух ключевых принципов обработки входных данных: валидация и приведение типов (casting / coercion). Понимание различий между строгим режимом и режимом приведения типов критично для предсказуемого поведения схем, особенно в формах, API и слоях обработки пользовательского ввода.
Перед тем как разбирать режимы, важно понимать внутренний цикл работы схемы:
transform)required,
min, matches и т.д.)Ключевой момент: Yup по умолчанию не просто проверяет, но и изменяет данные.
Coercion — это автоматическое преобразование входных данных к ожидаемому типу схемы.
import * as Yup from "yup";
const schema = Yup.number();
schema.validateSync("42");
// 42 (number)
Здесь строка "42" автоматически преобразуется в число
42.
schema.validateSync("");
// NaN
Пустые значения часто приводятся к невалидным числам или
undefined, в зависимости от схемы.
const schema = Yup.boolean();
schema.validateSync("true"); // true
schema.validateSync("false"); // false
schema.validateSync("1"); // true
Входные строковые значения интерпретируются как логические.
Strict mode полностью отключает автоматическое преобразование значений.
const schema = Yup.number().strict(true);
schema.validateSync("42");
// ValidationError
Здесь строка "42" не будет преобразована в
число, а сразу вызовет ошибку.
При strict(true):
transform) могут сохраняться, но без
coercion логики типаconst loose = Yup.number();
const strict = Yup.number().strict(true);
loose.validateSync("10");
// 10
strict.validateSync("10");
// Error
const schema = Yup.boolean().strict(true);
schema.validateSync("true");
// Error
Coercion особенно важен в следующих сценариях:
Поля формы всегда приходят как строки:
<input type="number" />
Фактическое значение:
"123"
Yup автоматически приводит его к числу без дополнительного кода.
API может присылать несогласованные типы:
{
"age": "25"
}
Coercion приводит данные к нужному виду без ручной обработки.
В связке с React Hook Form или Formik coercion снижает количество преобразований на уровне UI.
Strict mode используется, когда важна жёсткая типизация входных данных.
Если сервис ожидает строго типизированный JSON:
const schema = Yup.object({
id: Yup.number().strict(true)
});
Строковое "1" будет считаться ошибкой.
Когда важно исключить неявные преобразования:
Coercion может скрывать ошибки:
Yup.number().validateSync("abc");
// NaN (иногда проходит дальше)
Strict mode предотвращает такие ситуации.
Strict mode не отменяет возможность трансформаций:
const schema = Yup.string()
.strict(true)
.transform((value) => value.trim());
Здесь:
Yup имеет два уровня работы:
cast() — приводит типыvalidate() — проверяет и при необходимости тоже
каститschema.cast("42"); // 42
schema.cast("42"); // "42"
Cast перестаёт изменять тип данных.
Yup.number().validateSync(undefined);
// undefined проходит или становится NaN в зависимости от схемы
Yup.number().strict(true).validateSync(undefined);
// чаще всего ошибка required (если не optional)
Strict mode не отменяет optional():
Yup.number()
.strict(true)
.optional();
undefined допустим"123" всё равно не будет преобразованYup.number().strict(true).validateSync("10");
Ожидание: 10 Факт: ошибка
Внешние API часто возвращают строки вместо чисел. Strict schema ломает интеграцию.
schema.cast(value)
Может вести себя иначе в strict и non-strict режимах, что приводит к несоответствиям между UI и backend.
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)
});
Те же данные вызовут ошибку валидации.
Работа с этими режимами напрямую определяет предсказуемость схем и уровень контроля над входящими значениями в приложении.