Метод transform в библиотеке Yup используется для
предварительного преобразования входных значений перед выполнением
валидации. Он позволяет модифицировать сырые данные, поступающие в
схему, не изменяя исходный источник, но влияя на то, как эти данные
будут интерпретироваться валидатором.
Основная идея заключается в том, что входное значение проходит через функцию трансформации, и уже результат этой функции становится объектом дальнейшей проверки правил схемы.
Yup.string().transform((value, originalValue) => {
return transformedValue;
});
Функция transform принимает два аргумента:
Возвращаемое значение становится новым значением поля в рамках схемы.
Процесс обработки значения внутри схемы можно описать последовательностью:
transform (если он задан)required, min,
max и т.д.)Таким образом, transform выполняется до основной
валидации и влияет на итоговый результат проверки.
nullОдин из наиболее распространённых сценариев — нормализация пустых строк:
const schema = Yup.string().transform((value, originalValue) => {
return originalValue === "" ? null : value;
});
В этом случае пустая строка не проходит как валидное значение, а
преобразуется в null, что позволяет использовать
nullable():
const schema = Yup.string()
.nullable()
.transform((value, originalValue) => {
return originalValue === "" ? null : value;
});
Несмотря на то, что в Yup уже существует number() с
автоматическим преобразованием, transform позволяет более
гибко управлять конвертацией:
const schema = Yup.number().transform((value, originalValue) => {
return originalValue === "" ? undefined : Number(originalValue);
});
Здесь пустая строка превращается в undefined, что
позволяет избежать ошибок при обязательной числовой валидации.
Часто требуется удаление лишних пробелов:
const schema = Yup.string().transform((value) => {
return typeof value === "string" ? value.trim() : value;
});
Такой подход обеспечивает нормализацию данных до применения правил
min, max, matches.
transform часто используется для приведения текста к
единому формату:
const schema = Yup.string().transform((value) => {
return typeof value === "string" ? value.toLowerCase() : value;
});
Это особенно полезно при сравнении значений, например email или кодов:
Yup.string()
.email()
.transform((value) => value?.toLowerCase());
transform позволяет учитывать исходное значение и тип
данных:
const schema = Yup.mixed().transform((value, originalValue) => {
if (originalValue === "none") return null;
if (typeof originalValue === "string") return originalValue.trim();
return value;
});
Такая конструкция позволяет строить сложные правила нормализации данных до валидации.
undefined и
nullОсобое поведение возникает при возврате специальных значений:
undefined — значение считается отсутствующимnull — значение сохраняется как явно пустое (если
разрешено через nullable())const schema = Yup.string()
.nullable()
.transform((value, originalValue) => {
if (originalValue === "") return null;
if (originalValue === "skip") return undefined;
return value;
});
При использовании цепочек методов:
Yup.string()
.transform(...)
.required()
.min(5);
трансформация происходит до required и min.
Это означает, что результат transform влияет на логику всех
последующих правил.
Метод доступен не только для строк и чисел, но и для сложных типов:
const schema = Yup.object().transform((value, originalValue) => {
return {
...value,
createdAt: new Date(),
};
});
const schema = Yup.array().transform((value) => {
return Array.isArray(value) ? value.filter(Boolean) : value;
});
originalValueЧастая проблема — использование только value, что может
привести к потере исходного контекста:
// менее надёжный вариант
transform((value) => value === "" ? null : value);
Более корректный подход:
transform((value, originalValue) => originalValue === "" ? null : value);
Возвращаемое значение должно соответствовать ожидаемому типу схемы. Например, возврат строки в числовой схеме может привести к ошибкам или неожиданным результатам валидации.
Функция transform должна оставаться чистой.
Использование внешних состояний, API-запросов или мутаций данных
приводит к непредсказуемому поведению схемы.
castYup различает transform и cast. Первый
применяется на этапе подготовки значения, второй — при приведении
типов:
schema.cast(value);
transform выполняется до cast, что
позволяет заранее нормализовать данные перед приведением типов.
В формах transform часто применяется для стандартизации
пользовательского ввода:
Это снижает нагрузку на последующие правила валидации и упрощает логику схем.
stripВзаимодействие с strip() влияет на результат схемы:
Yup.string()
.transform((v) => v?.trim())
.strip();
Если значение помечено как strip, оно полностью
исключается из результата, даже если прошло трансформацию.
При глубоко вложенных схемах с множественными transform
важно учитывать: