Приведение типов в Yup основано на механизме кастинга (casting), который выполняется до этапа валидации и определяет, в какой форме данные будут интерпретироваться внутри схемы. Это поведение делает библиотеку удобной для работы с формами и внешними источниками данных, где значения часто приходят в виде строк.
Каждая схема в Yup не только проверяет данные, но и приводит их к
ожидаемому типу. Это происходит через внутренний метод
cast(), который применяется:
schema.cast(value)validate)Важно понимать, что приведение типов и валидация — это разные этапы. Сначала выполняется преобразование, затем проверка ограничений.
По умолчанию Yup работает в нестрогом режиме:
schema.validate(value, { strict: false })
В этом режиме происходит автоматическое приведение типов:
"123" преобразуются в число
123"true" и "false" могут интерпретироваться
как булевы значения (в зависимости от схемы)DateЕсли включить строгий режим:
schema.validate(value, { strict: true })
приведение отключается, и данные проверяются «как есть».
Наиболее распространённый случай — преобразование строк в числа:
import * as yup from 'yup';
const schema = yup.number();
schema.cast("42"); // 42 (number)
schema.cast("42px"); // NaN
schema.cast(""); // NaN
Особенности поведения:
"" преобразуется в NaNNaN.required(),
.positive(), .integer() и другие правилаПример с валидацией:
const schema = yup.number().required().positive();
schema.validate("10"); // 10
schema.validate("-5"); // ошибка (negative)
Строковые схемы обычно не требуют сложного приведения, но Yup всё равно нормализует входные данные:
const schema = yup.string();
schema.cast(123); // "123"
schema.cast(null); // "null" (если не nullable)
schema.cast(undefined); // undefined
Особенность: любые примитивы приводятся к строке через стандартное
String(value).
Для ограничения поведения используется:
yup.string().nullable();
yup.string().strict(true);
Булев тип является одним из самых неоднозначных:
const schema = yup.boolean();
schema.cast("true"); // true
schema.cast("false"); // false
schema.cast(1); // true
schema.cast(0); // false
Поведение основано на внутренних правилах интерпретации «truthy/falsy» значений. Однако важно учитывать, что строковые значения обрабатываются явно, а не через JavaScript-приведение.
При использовании yup.date() происходит попытка создания
объекта Date:
const schema = yup.date();
schema.cast("2024-01-01"); // Date объект
schema.cast(1704067200000); // Date из timestamp
Если значение не может быть преобразовано:
schema.cast("invalid date"); // Invalid Date
Дальнейшая валидация через .typeError() или
.min() / .max() позволяет контролировать
корректность.
Ключевым инструментом управления приведением типов является метод
transform:
const schema = yup.number().transform((value, originalValue) => {
if (typeof originalValue === "string") {
return originalValue.trim() === "" ? undefined : Number(originalValue);
}
return value;
});
Функция transform получает:
value — уже приведённое значениеoriginalValue — исходное значение до кастингаЭтот механизм позволяет:
При вызове:
schema.validate(value)
выполняется последовательность:
cast(value)transform (если задан)required, min,
max, и т.д.)Прямой вызов:
schema.cast(value)
выполняет только этап приведения без валидации.
При использовании .default() происходит приведение
значения по той же логике:
const schema = yup.number().default("10");
schema.cast(undefined); // 10 (number)
Если значение по умолчанию несовместимо с типом, оно также проходит кастинг.
Схема:
yup.string().nullable()
позволяет сохранить null без преобразования:
schema.cast(null); // null
Без nullable() значение может быть преобразовано в
строку "null".
Для составных схем приведение выполняется рекурсивно:
const schema = yup.object({
age: yup.number(),
name: yup.string()
});
schema.cast({
age: "25",
name: 123
});
Результат:
{
age: 25,
name: "123"
}
Для массивов:
const schema = yup.array().of(yup.number());
schema.cast(["1", "2", "3"]); // [1, 2, 3]
Автоматическое приведение может приводить к неоднозначным ситуациям:
NaN в числах"false" всегда интерпретируется как
falseInvalid Date, но не
выбрасывают ошибку сразуПоэтому важно контролировать поведение через:
strict(true)transform().typeError()Порядок обработки значения внутри схемы:
casttransformЭтот порядок определяет итоговое значение, которое возвращается после
validate.
undefined обрабатывается отдельно:
.default()undefined, если не задано обязательное
поле.required()yup.number().required().validate(undefined); // ошибка
Механизм приведения типов в Yup строится на комбинации:
Эта модель делает возможным единообразную обработку входных данных из форм, API и внешних источников без необходимости ручного преобразования на уровне бизнес-логики.