Метод transform

Метод transform в библиотеке Yup используется для предварительного преобразования входных значений перед выполнением валидации. Он позволяет модифицировать сырые данные, поступающие в схему, не изменяя исходный источник, но влияя на то, как эти данные будут интерпретироваться валидатором.

Основная идея заключается в том, что входное значение проходит через функцию трансформации, и уже результат этой функции становится объектом дальнейшей проверки правил схемы.


Базовый синтаксис

Yup.string().transform((value, originalValue) => {
  return transformedValue;
});

Функция transform принимает два аргумента:

  • value — текущее значение после предыдущих трансформаций
  • originalValue — исходное значение до любых преобразований

Возвращаемое значение становится новым значением поля в рамках схемы.


Механизм работы трансформации

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

  1. Получение исходного значения
  2. Применение transform (если он задан)
  3. Применение встроенных преобразований Yup (например, приведение типов)
  4. Запуск валидаторов (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-запросов или мутаций данных приводит к непредсказуемому поведению схемы.


Комбинирование с cast

Yup различает transform и cast. Первый применяется на этапе подготовки значения, второй — при приведении типов:

schema.cast(value);

transform выполняется до cast, что позволяет заранее нормализовать данные перед приведением типов.


Использование валидации форм

В формах transform часто применяется для стандартизации пользовательского ввода:

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

Это снижает нагрузку на последующие правила валидации и упрощает логику схем.


Поведение при strip

Взаимодействие с strip() влияет на результат схемы:

Yup.string()
  .transform((v) => v?.trim())
  .strip();

Если значение помечено как strip, оно полностью исключается из результата, даже если прошло трансформацию.


Производительность и сложные схемы

При глубоко вложенных схемах с множественными transform важно учитывать:

  • каждая функция вызывается при каждой валидации
  • сложные вычисления внутри трансформации замедляют обработку
  • предпочтительно избегать тяжёлых операций (например, парсинга JSON без необходимости)

Итоговые особенности поведения

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