Lowercase и uppercase преобразования

В библиотеке Yup работа со строками строится вокруг цепочки методов, которые последовательно применяют преобразования и проверки. Приведение строк к нижнему и верхнему регистру относится к стадии трансформации значения до выполнения валидации, что позволяет унифицировать входные данные и снизить вероятность ошибок при сравнении или проверке формата.

Трансформации выполняются до валидаторов (min, max, matches и других), поэтому итоговое значение, которое проходит проверку, уже может отличаться от исходного пользовательского ввода.


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

Любая строковая схема в Yup начинается с yup.string(). На этом уровне значение ещё не модифицировано, но уже определён тип данных. Далее к схеме могут применяться трансформации:

  • lowercase()
  • uppercase()
  • trim()
  • transform()

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


Приведение к нижнему регистру (lowercase)

Метод lowercase() преобразует все символы строки в нижний регистр, используя стандартную реализацию JavaScript String.prototype.toLowerCase().

import * as yup from "yup";

const schema = yup.object({
  email: yup.string().required().lowercase(),
});

При валидации значение:

"User@Example.COM"

будет преобразовано в:

"user@example.com"

и именно эта версия попадёт в результирующий объект после validate.

Особенности поведения lowercase

  • Применяется до проверок формата (matches, email и т.д.)
  • Не изменяет исходный объект, а возвращает новое значение
  • Подходит для нормализации идентификаторов (email, username, slug)

Приведение к верхнему регистру (uppercase)

Метод uppercase() выполняет обратную операцию, приводя строку к верхнему регистру через String.prototype.toUpperCase().

const schema = yup.object({
  countryCode: yup.string().length(2).uppercase(),
});

Пример входного значения:

"us"

После трансформации:

"US"

Практическое применение uppercase

  • Коды стран (ISO)
  • Системные идентификаторы
  • Маркеры статусов
  • Константные строковые значения

Порядок выполнения трансформаций

Yup выполняет цепочку слева направо. Это влияет на итоговое значение:

const schema = yup.string().trim().lowercase();

Сначала выполняется trim(), затем lowercase():

Вход:

"  HeLLo  "

Результат:

"hello"

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


Использование transform для ручного управления регистром

Метод transform() позволяет реализовать кастомную логику преобразования, включая условия и сложные правила обработки строки.

const schema = yup.string().transform((value, originalValue) => {
  if (typeof originalValue === "string") {
    return originalValue.toLowerCase().replace(/\s+/g, "_");
  }
  return value;
});

Здесь одновременно выполняется:

  • приведение к нижнему регистру
  • замена пробелов на подчёркивания

Пример:

"Hello World Test"

Результат:

"hello_world_test"

Взаимодействие с валидацией

Важно учитывать, что после применения lowercase() или uppercase() валидаторы работают уже с преобразованным значением.

const schema = yup.string()
  .lowercase()
  .matches(/^[a-z]+$/);

Даже если исходный ввод содержал заглавные буквы, проверка matches будет выполняться после приведения к нижнему регистру.


Комбинация с trim и другими строковыми методами

Часто преобразование регистра используется совместно с очисткой пробелов:

const schema = yup.string()
  .trim()
  .lowercase()
  .min(3)
  .max(20);

Такая комбинация обеспечивает:

  • отсутствие лишних пробелов
  • единый регистр
  • корректную длину строки

Unicode и локализация

Методы toLowerCase() и toUpperCase() учитывают Unicode, однако поведение может различаться для некоторых языков.

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

  • Турецкий язык (Iı, İi) может давать неожиданные результаты
  • Некоторые символы не имеют пары в другом регистре
  • Эмодзи и символы без регистра остаются неизменными

Это важно учитывать при обработке интернациональных данных, особенно в глобальных приложениях.


Повторное применение и переопределение

Если в цепочке несколько раз применяются трансформации регистра, итоговым будет результат последнего вызова:

yup.string()
  .lowercase()
  .uppercase()

В этом случае итоговое значение будет в верхнем регистре, так как uppercase() выполняется последним.


Валидация и нормализация идентификаторов

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

const schema = yup.object({
  username: yup.string().lowercase().required(),
});

Это позволяет гарантировать, что:

  • UserName
  • USERNAME
  • username

будут приведены к одному виду.


Схемы с переиспользованием

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

const baseString = yup.string().trim().lowercase();

const userSchema = yup.object({
  login: baseString.min(3).max(30),
  email: baseString.email().required(),
});

Такой подход обеспечивает единообразие обработки строк по всему приложению.


Потенциальные проблемы и тонкости

Несмотря на простоту методов, существуют нюансы:

  • Трансформация может скрыть исходную ошибку ввода (например, пользователь вводит EMAIL@TEST.COM, а ошибка отображается уже на изменённом значении)
  • Валидация регулярными выражениями может стать слишком permissive после приведения регистра
  • Некоторые API требуют строго сохранения регистра (например, пароли), где применение lowercase() недопустимо

Поведение при null и undefined

Трансформации регистра не применяются к null и undefined. Эти значения обрабатываются валидаторами required() и nullable().

yup.string().lowercase().required()
  • undefined → ошибка required
  • null → зависит от настройки nullable()
  • строка → преобразуется к нижнему регистру

Итоговая модель обработки строки

Внутренний порядок обработки можно представить как последовательность:

  1. Получение значения
  2. Применение transform()
  3. trim(), lowercase(), uppercase()
  4. Проверки (min, max, matches, email)
  5. Возврат итогового значения

Эта модель делает Yup предсказуемым инструментом нормализации и валидации строковых данных.