Логические значения: boolean schema

Булевый тип в Yup используется для валидации значений, которые должны строго соответствовать логическому типу boolean. Несмотря на кажущуюся простоту, работа с булевыми значениями в реальных формах и API требует учёта множества нюансов: преобразование строковых значений, обработка неопределённых состояний, поведение чекбоксов, строгая типизация и кастомные правила.


Базовое определение булевой схемы

В Yup булевый тип создаётся через фабричный метод:

import * as yup from 'yup';

const schema = yup.boolean();

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

  • true
  • false

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


Приведение типов (casting) и неявные преобразования

Одной из ключевых особенностей Yup является автоматическое приведение типов. При включённой стандартной конфигурации библиотека пытается интерпретировать входные данные и привести их к boolean.

Строковые значения

Часто данные поступают в виде строк:

schema.cast("true");  // true
schema.cast("false"); // false

Также учитываются числовые представления:

schema.cast(1); // true
schema.cast(0); // false

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


Строгий режим (strict mode)

При включении строгого режима отключается автоматическое преобразование типов:

const schema = yup.boolean().strict();

В этом режиме:

  • "true" не будет преобразовано в true
  • 1 не будет преобразовано в true
  • любые не-boolean значения приводят к ошибке валидации

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


Обязательность значения

Булевый тип по умолчанию допускает undefined, если не указано обратное.

const schema = yup.boolean().required();

В таком случае:

  • true — допустимо
  • false — допустимо
  • undefined — ошибка валидации

Важно учитывать, что required() проверяет наличие значения, но не запрещает false, так как это валидное булево значение.


Ограничение допустимых значений

Для строгого контроля допустимых состояний используется метод oneOf:

Разрешено только true

const schema = yup.boolean().oneOf([true]);

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

  • согласие обязательно
  • отсутствие значения или false — ошибка

Разрешено только false

const schema = yup.boolean().oneOf([false]);

Используется реже, но может применяться для инверсных флагов.


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

Булевый тип поддерживает установку дефолтного значения:

const schema = yup.boolean().default(false);

При отсутствии значения:

  • автоматически подставляется false

Если значение приходит явно, дефолт игнорируется.


Nullable и работа с null

По умолчанию null не считается валидным значением:

const schema = yup.boolean();
schema.validateSync(null); // ошибка

Разрешение null:

const schema = yup.boolean().nullable();

В этом случае:

  • true — допустимо
  • false — допустимо
  • null — допустимо

Разница между null и undefined критична:

  • undefined чаще означает отсутствие поля
  • null — явно заданное пустое значение

Ошибки типов и кастомизация сообщений

При несоответствии типа используется стандартное сообщение, которое можно переопределить:

const schema = yup.boolean().typeError('Ожидается логическое значение');

Также можно задавать индивидуальные сообщения для конкретных правил:

const schema = yup
  .boolean()
  .oneOf([true], 'Необходимо подтвердить условие');

Использование с формами и чекбоксами

Булевый тип наиболее часто применяется в связке с UI-элементами:

  • чекбоксы согласия
  • переключатели (toggle)
  • флаги состояния

Пример схемы:

const schema = yup.object({
  termsAccepted: yup.boolean().oneOf([true]),
  newsletter: yup.boolean().default(false),
});

Особенность HTML-форм заключается в том, что:

  • чекбокс без отметки часто возвращает undefined
  • при отметке возвращает true

Поэтому required() без oneOf([true]) часто недостаточен для логики согласия.


Поведение при отсутствии значения

Без required() и default() поведение выглядит следующим образом:

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

Это важно учитывать при валидации частичных форм и PATCH-запросов.


Кастомные проверки через test

Для более сложной логики используется метод test:

const schema = yup.boolean().test(
  'is-true-check',
  'Значение должно быть истинным',
  (value) => value === true
);

Такой подход позволяет реализовать:

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

Взаимодействие с трансформациями

Метод transform позволяет явно контролировать приведение значений:

const schema = yup.boolean().transform((value, originalValue) => {
  if (originalValue === 'yes') return true;
  if (originalValue === 'no') return false;
  return value;
});

Это полезно при работе с нестандартными API, где boolean кодируется строками или нестандартными флагами.


Частые сценарии использования

Обязательное согласие

yup.boolean().oneOf([true]).required();

Опциональный флаг

yup.boolean().default(false);

Nullable флаг состояния

yup.boolean().nullable();

Строгая типизация без преобразований

yup.boolean().strict().required();

Особенности поведения в сложных схемах

При вложении в object булевы поля наследуют поведение корневой схемы:

const schema = yup.object({
  isActive: yup.boolean().default(true),
});

При отсутствии значения:

  • автоматически применяется true
  • если поле отсутствует полностью, работает default

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

yup.array().of(yup.boolean());

Типичные ошибки при использовании

  • использование required() вместо oneOf([true]) для чекбоксов согласия
  • ожидание автоматического преобразования строк в строгом режиме
  • игнорирование различий между null и undefined
  • отсутствие default при логических флагах, что приводит к undefined в состоянии формы

Поведение в режиме кастинга

При включённом кастинге Yup интерпретирует входные значения:

  • "true"true
  • "false"false
  • 1true
  • 0false
  • пустая строка может интерпретироваться как false или undefined в зависимости от контекста

Это поведение важно учитывать при интеграции с формами, особенно при использовании библиотек вроде Formik или React Hook Form.


Совместимость с другими типами схем

Булевый тип часто комбинируется с:

  • when() — условная логика
  • mixed() — расширенные типы
  • object() — вложенные структуры

Пример условной логики:

yup.object({
  isEnabled: yup.boolean(),
  value: yup.string().when('isEnabled', {
    is: true,
    then: yup.string().required(),
  }),
});

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