@IsBoolean

Декоратор @IsBoolean() из библиотеки class-validator применяется для проверки того, что значение свойства является булевым типом (true или false) и не относится к другим “псевдобулевым” значениям, таким как строки "true", "false", числа 0 и 1, или любые другие значения, которые могут интерпретироваться как логические в JavaScript.

Основная задача декоратора — строгая валидация типа данных на уровне DTO-моделей, чаще всего в связке с class-transformer и фреймворками наподобие NestJS.


Проверка, выполняемая @IsBoolean(), основана на строгом сравнении типа значения:

  • допустимые значения: true, false
  • недопустимые значения: любые строки, числа, объекты, null, undefined

Фактически используется проверка эквивалентная:

typeof value === 'boolean'

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


Базовое применение

import { IsBoolean } from 'class-validator';

export class UpdateUserDto {
  @IsBoolean()
  isActive: boolean;
}

В этом примере поле isActive обязано содержать строго булево значение. Передача "true" или 1 приведёт к ошибке валидации.


Поведение при разных входных данных

Входное значение Результат
true проходит
false проходит
"true" ошибка
"false" ошибка
1 ошибка
0 ошибка
null ошибка
undefined ошибка
{} ошибка

Влияние преобразования данных

В реальных приложениях (особенно в HTTP API) данные часто приходят в виде строк. Например:

{
  "isActive": "true"
}

Без дополнительного преобразования class-validator не изменяет тип данных. Поэтому строка "true" останется строкой и не пройдет проверку @IsBoolean().

Для корректной работы обычно используется class-transformer:

import { Transform } from 'class-transformer';
import { IsBoolean } from 'class-validator';

export class UpdateUserDto {
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  isActive: boolean;
}

Здесь происходит явное преобразование строки в булево значение до этапа валидации.


Работа в NestJS ValidationPipe

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

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);

Однако даже при включённом transform: true, автоматическое преобразование "true"true не происходит без class-transformer декораторов.


Валидация массивов булевых значений

Для проверки массива используется параметр each: true:

import { IsBoolean } from 'class-validator';

export class FlagsDto {
  @IsBoolean({ each: true })
  flags: boolean[];
}

Здесь каждый элемент массива проверяется отдельно. Например:

  • [true, false, true] — проходит
  • [true, "false"] — ошибка

Кастомизация сообщения об ошибке

Можно задать собственный текст ошибки:

import { IsBoolean } from 'class-validator';

export class UpdateDto {
  @IsBoolean({ message: 'Поле isActive должно быть логическим значением' })
  isActive: boolean;
}

Сообщение возвращается в стандартном формате ошибок валидации.


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

class-validator поддерживает группы, позволяя применять проверку условно:

import { IsBoolean } from 'class-validator';

export class UserDto {
  @IsBoolean({ groups: ['create'] })
  isActive: boolean;
}

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

validate(dto, { groups: ['create'] });

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


Сочетание с другими декораторами

В реальных DTO @IsBoolean() часто используется вместе с другими ограничениями:

import { IsBoolean, IsOptional } from 'class-validator';

export class UpdateSettingsDto {
  @IsOptional()
  @IsBoolean()
  emailNotifications?: boolean;
}

Здесь поле становится необязательным, но при наличии значения оно обязано быть строго булевым.


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

Передача строковых значений

Наиболее распространённая проблема — ожидание автоматического приведения типов:

isActive: "false"

Такое значение не преобразуется автоматически и приводит к ошибке.


Путаница с truthy/falsy значениями

JavaScript допускает неявные преобразования:

  • "text" → true
  • 1 → true

Но @IsBoolean() не учитывает подобные преобразования, так как работает только с типом boolean.


Отсутствие class-transformer

Без явного трансформирования входных данных даже корректные API-запросы часто не проходят валидацию.


Поведение с undefined и optional полями

При отсутствии декоратора @IsOptional():

class Dto {
  @IsBoolean()
  isActive: boolean;
}

undefined рассматривается как нарушение, поскольку поле обязательно.

С @IsOptional():

class Dto {
  @IsOptional()
  @IsBoolean()
  isActive?: boolean;
}

Отсутствие поля допускается, но при наличии значение строго проверяется.


Внутренние особенности реализации

Внутри class-validator используется механизм декораторов на базе metadata reflection. Проверка выполняется через зарегистрированные валидаторы, где IsBoolean реализует проверку типа без приведения значения.

Логика сводится к проверке:

  • значение не null
  • значение не undefined
  • typeof value === 'boolean'

Типовые сценарии применения

Флаги состояния

class FeatureToggleDto {
  @IsBoolean()
  isEnabled: boolean;
}

Настройки пользователя

class SettingsDto {
  @IsBoolean()
  darkMode: boolean;

  @IsBoolean()
  emailVerified: boolean;
}

Управление доступом

class PermissionDto {
  @IsBoolean()
  canEdit: boolean;

  @IsBoolean()
  canDelete: boolean;
}

Поведение при сериализации и десериализации

При работе с API данные часто проходят несколько этапов:

  1. JSON → объект
  2. трансформация (class-transformer)
  3. валидация (class-validator)

@IsBoolean() вступает в работу строго на этапе 3, поэтому любые несоответствия типов, возникшие на этапе 1–2, остаются критичными без явной обработки.


Ограничения использования

  • не выполняет приведение типов
  • не интерпретирует строки как boolean
  • не работает с truthy/falsy логикой JavaScript
  • не заменяет бизнес-валидацию (например, зависимость между полями)

Поведение в сложных структурах

При использовании вложенных DTO:

import { ValidateNested, IsBoolean } from 'class-validator';
import { Type } from 'class-transformer';

class InnerDto {
  @IsBoolean()
  flag: boolean;
}

class OuterDto {
  @ValidateNested()
  @Type(() => InnerDto)
  config: InnerDto;
}

валидация проходит рекурсивно, и @IsBoolean() применяется к вложенному свойству flag после трансформации объекта.