Строковые значения и их валидация

Роль строк в валидации схем

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

Строка в контексте Yup рассматривается не как «просто текст», а как объект с набором трансформаций и правил, применяемых последовательно.

Базовое объявление строковой схемы

Основой работы со строками является метод string():

import * as yup from "yup";

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

Такое определение гарантирует, что поле username будет интерпретировано как строковое значение. Однако без дополнительных ограничений любая строка, включая пустую, считается валидной.

Обязательность строковых значений

Контроль обязательности реализуется через required():

const schema = yup.object({
  username: yup.string().required("Поле обязательно для заполнения")
});

Механика проверки:

  • undefined → ошибка
  • null → ошибка (если не разрешено явно)
  • "" → ошибка, если не переопределено поведение

Строковые поля часто требуют явного указания обязательности, поскольку пустая строка считается валидным значением JavaScript-типа string.

Ограничение длины строки

Yup предоставляет инструменты для контроля длины:

const schema = yup.object({
  username: yup
    .string()
    .min(3, "Минимум 3 символа")
    .max(20, "Максимум 20 символов")
});

Логика применения:

  • min(n) — проверка нижней границы длины
  • max(n) — проверка верхней границы длины

Обе проверки выполняются после приведения значения к строке.

Проверка формата строки через регулярные выражения

Метод matches() используется для строгой валидации формата:

const schema = yup.object({
  username: yup
    .string()
    .matches(/^[a-zA-Z0-9_]+$/, "Недопустимые символы")
});

Типичные сценарии:

  • логины
  • коды
  • идентификаторы
  • алиасы

Регулярное выражение применяется к уже преобразованной строке, что позволяет централизованно управлять правилами формата.

Встроенные типовые проверки строк

Yup включает специализированные методы для распространённых сценариев.

Проверка email

email: yup.string().email("Некорректный email")

Внутри используется набор предопределённых правил RFC-формата с упрощениями для практического применения.

Проверка URL

website: yup.string().url("Некорректный URL")

Проверяется структура протокола, домена и пути.

UUID и другие форматы

id: yup.string().uuid("Некорректный UUID")

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

Трансформация строковых значений

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

Обрезка пробелов

username: yup.string().trim()

Удаляет пробелы в начале и конце строки до применения остальных правил.

Приведение пустых значений

comment: yup.string().nullable()

Позволяет явно разрешить null как допустимое значение.

Замена пустых строк

bio: yup.string().transform((value) => {
  return value === "" ? null : value;
})

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

Значения по умолчанию

Строковые поля могут иметь дефолтные значения:

const schema = yup.object({
  nickname: yup.string().default("guest")
});

При отсутствии значения в данных формы автоматически подставляется указанная строка.

Комбинирование правил валидации

Строковая схема часто представляет собой цепочку ограничений:

const schema = yup.object({
  username: yup
    .string()
    .trim()
    .required("Обязательное поле")
    .min(3, "Слишком короткое")
    .max(15, "Слишком длинное")
    .matches(/^[a-z0-9_]+$/, "Только латиница, цифры и _")
});

Порядок имеет значение:

  1. трансформация (trim)
  2. обязательность (required)
  3. длина (min, max)
  4. формат (matches)

Такой порядок снижает количество ложных ошибок и упрощает диагностику.

Поведение при несовпадении типов

Если значение не является строкой, Yup пытается привести его:

  • число → строка "123"
  • boolean → "true" / "false"
  • null → зависит от nullable()

Явное управление типами позволяет избежать неожиданных преобразований:

yup.string().strict(true)

В строгом режиме автоматическое приведение отключается.

Работа с пустыми значениями

Пустая строка является отдельным случаем, отличным от undefined и null.

Контроль поведения:

yup.string().required()
yup.string().notRequired()
yup.string().nullable()

Комбинации позволяют точно задавать допустимые состояния поля.

Условная валидация строк

Строковые поля могут зависеть от других значений схемы:

passwordConfirm: yup.string().when("password", (password, schema) => {
  return schema.oneOf([password], "Пароли не совпадают");
});

Механизм when() позволяет строить динамические правила, где строковая валидация зависит от контекста формы.

Интеграция с YupResolver в форме

При использовании YupResolver строковые правила передаются в резолвер, который преобразует ошибки Yup в структуру, понятную системе формы:

import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

const { register, handleSubmit, formState } = useForm({
  resolver: yupResolver(schema)
});

Особенности обработки:

  • каждая строковая ошибка привязывается к конкретному полю
  • сообщения берутся из схемы Yup
  • преобразования применяются до валидации
  • результат синхронизируется с состоянием формы

Локализация сообщений для строковых правил

Строковые ограничения поддерживают кастомизацию сообщений:

yup.string().min(5, ({ min }) => `Минимум ${min} символов`)

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

Производительность строковой валидации

Строковые проверки в Yup оптимизированы для последовательного выполнения:

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

При использовании через YupResolver повторные пересчёты минимизируются за счёт кеширования состояния формы.

Типовые ошибки при работе со строками

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

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