Описание схем через describe

В библиотеке Yup метод describe() используется для получения структурированного описания схемы в виде обычного JavaScript-объекта. Это описание отражает внутреннюю структуру валидатора без выполнения самой валидации и без необходимости запускать проверку данных.

Ключевая особенность describe() заключается в том, что он переводит декларативную схему в формат, удобный для анализа, сериализации, генерации интерфейсов и динамической работы с формами. При этом возвращаемая структура не содержит бизнес-логики проверки, а представляет собой метаданные схемы.

Общая структура результата describe()

Результат вызова schema.describe() представляет собой объект со следующими ключевыми компонентами:

  • type — тип узла схемы (string, number, object, array, boolean, date, mixed)
  • label — метка, заданная через .label()
  • tests — список применённых правил валидации
  • fields — структура вложенных полей (для объектов)
  • innerType — описание элементов массива (для array-схем)
  • oneOf / notOneOf — ограничения на допустимые значения
  • nullable / optional — информация о допустимости null и отсутствующих значений
  • default — значение по умолчанию

Эта структура может быть вложенной, отражая глубину схемы любой сложности.

Описание примитивных типов

Для простых типов данных describe() возвращает компактную структуру, содержащую базовую информацию о валидаторах.

Строки

const schema = Yup.string().min(3).max(10).required();
console.log(schema.describe());

Результат включает:

  • type: "string"
  • tests: min, max, required
  • дополнительные параметры, если заданы ограничения формата (например, email, url, matches)

Каждое правило представлено как объект с именем теста и его параметрами.

Числа

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

Yup.number().min(0).max(100).integer()

Описание будет содержать:

  • min
  • max
  • integer
  • positive, negative при соответствующих ограничениях

Описание объектов

Объектные схемы формируют древовидную структуру через поле fields.

const schema = Yup.object({
  name: Yup.string().required(),
  age: Yup.number().min(18),
});

Результат describe():

  • type: "object"

  • fields:

    • name: описание строковой схемы
    • age: описание числовой схемы

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

Особенность описания объектов заключается в том, что оно сохраняет иерархию без потери контекста вложенности, включая вложенные объекты:

Yup.object({
  user: Yup.object({
    email: Yup.string().email(),
  }),
});

В describe() вложенные уровни представлены рекурсивно через fields.

Описание массивов

Массивы используют поле innerType, которое описывает структуру элементов.

const schema = Yup.array().of(Yup.number().positive());

Описание включает:

  • type: "array"

  • innerType:

    • type: "number"
    • tests: positive

Если массив содержит сложные объекты, innerType становится вложенной структурой с fields, аналогично объектам.

Дополнительные свойства в describe()

Условные ограничения

При использовании методов вроде when() структура описания может включать дополнительные зависимости, однако они не всегда полностью разворачиваются в статическое дерево. Вместо этого фиксируется факт наличия условной логики.

Nullable и optional

Схемы различают:

  • nullable: true — допустимость null
  • optional: true — отсутствие значения

Это важно при генерации форм и API-спецификаций.

OneOf и notOneOf

Yup.string().oneOf(["admin", "user"])

В описании появляется:

  • oneOf: ["admin", "user"]

Это позволяет использовать схему как источник перечислений.

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

Генерация пользовательских интерфейсов

Один из наиболее распространённых сценариев использования describe() — построение динамических форм. На основе структуры схемы можно автоматически создавать:

  • текстовые поля
  • числовые инпуты
  • чекбоксы
  • выпадающие списки

Тип поля определяется через type, а ограничения через tests.

Документирование API

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

Валидация на клиенте и сервере

Хотя describe() не выполняет проверку данных, он может применяться для:

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

Анализ и трансформация схем

Структура, возвращаемая describe(), может быть сериализована в JSON и передана в другие системы. Это позволяет:

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

Ограничения метода describe()

Несмотря на полезность, describe() имеет ряд ограничений:

  • не всегда полностью раскрывает условную логику (when)
  • не содержит runtime-состояния валидации
  • может упрощать сложные кастомные тесты
  • не гарантирует обратное восстановление исходной схемы

Таким образом, describe() следует рассматривать как инструмент для анализа структуры, а не как полную сериализацию схемы.

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

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

Это делает возможным:

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