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

В экосистеме валидации данных для TypeScript и JavaScript библиотека class-validator предоставляет специализированные инструменты для работы с булевыми значениями, обеспечивая строгую проверку типов входных данных в DTO-объектах, моделях и слоях транспортировки данных.

Булевый тип (boolean) является одним из наиболее часто используемых примитивов в прикладной разработке. Он применяется для флагов состояния, разрешений, переключателей функциональности, признаков активности и множества других сценариев. Несмотря на простоту типа, в реальных приложениях данные часто приходят в некорректных или нестрогих формах: строки "true", "false", числа 0 и 1, а также произвольные значения, которые требуют нормализации и строгой проверки.

Базовая проверка булевого типа

Основным инструментом является декоратор @IsBoolean(). Он выполняет строгую проверку значения и допускает только истинные булевы типы true и false.

import { IsBoolean } from 'class-validator';

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

Поведение проверки:

  • true → допустимо
  • false → допустимо
  • "true" → недопустимо
  • 1 → недопустимо
  • 0 → недопустимо
  • null / undefined → поведение зависит от дополнительных декораторов (@IsOptional())

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

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

В прикладных сценариях данные часто приходят из HTTP-запросов, где все параметры сериализуются в строки. Для таких случаев используется @IsBooleanString().

import { IsBooleanString } from 'class-validator';

export class QueryDto {
  @IsBooleanString()
  isEnabled: string;
}

Допустимые значения:

  • "true"
  • "false"

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

  • значение проверяется как строка
  • допускаются только строго определённые литералы
  • регистр имеет значение в зависимости от реализации парсинга (обычно ожидается lowercase)

Различие между IsBoolean и IsBooleanString

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

Декоратор Ожидаемый тип Пример валидного значения
@IsBoolean() boolean true, false
@IsBooleanString() string "true", "false"

Использование неправильного декоратора приводит к ошибкам валидации даже при логически корректных данных, но неверном типе.

Проблема неявного преобразования типов

В JavaScript часто встречается автоматическое приведение типов, которое может приводить к ошибкам при валидации. Например, выражение:

Boolean("false") // true

возвращает true, поскольку непустая строка считается истинной. Это делает невозможным использование встроенного преобразования JavaScript для надёжной проверки логических значений.

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

Использование с трансформацией данных

Для корректной обработки входных данных часто применяется связка с class-transformer, где выполняется явное преобразование строки в булев тип до этапа валидации.

Пример нормализации:

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

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

Логика трансформации:

  • строка "true"true
  • любые другие значения → false

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

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

Некоторые API и источники данных используют числовое представление логических значений:

  • 1 → true
  • 0 → false

Для поддержки такого формата применяется кастомная трансформация:

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

export class NumericFlagDto {
  @Transform(({ value }) => value === 1 || value === '1')
  @IsBoolean()
  isDeleted: boolean;
}

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

Валидация опциональных булевых полей

При работе с частичными обновлениями данных необходимо учитывать отсутствие значения. Для этого используется @IsOptional().

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

export class PatchDto {
  @IsOptional()
  @IsBoolean()
  isArchived?: boolean;
}

Поведение:

  • отсутствие поля → валидно
  • true / false → валидно
  • некорректный тип → ошибка валидации

Вложенные структуры с булевыми значениями

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

import { IsBoolean } from 'class-validator';

class Permissions {
  @IsBoolean()
  canRead: boolean;

  @IsBoolean()
  canWrite: boolean;

  @IsBoolean()
  canDelete: boolean;
}

export class UserDto {
  permissions: Permissions;
}

При использовании вложенной валидации требуется дополнительный декоратор @ValidateNested(), однако логика булевой проверки остаётся неизменной.

Частые ошибки при валидации булевых значений

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

  • "false" интерпретируется как truthy в JavaScript
  • 0 и 1 не считаются булевыми типами
  • "0" и "1" требуют явной трансформации

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

Строгая типизация и совместимость с TypeScript

Использование class-validator в связке с TypeScript позволяет синхронизировать декларативные типы и runtime-валидацию. Однако TypeScript не выполняет проверку в рантайме, поэтому декораторы остаются обязательным механизмом контроля входных данных.

Булевый тип в TypeScript:

let isEnabled: boolean;

не защищает от получения значения "true" из внешнего источника данных, что делает runtime-валидацию критически важной.

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

При передаче данных через JSON булевые значения сериализуются корректно:

{
  "isActive": true
}

Однако при использовании форм-данных или query-параметров все значения преобразуются в строки, что требует дополнительной обработки через @Transform или использование @IsBooleanString().

Комбинирование с другими валидаторами

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

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

export class FeatureDto {
  @IsBoolean()
  isEnabled: boolean;

  @ValidateIf(o => o.isEnabled === true)
  @IsBoolean()
  isBetaFeature: boolean;
}

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

Роль булевой валидации в архитектуре приложений

Булевые поля часто выступают как управляющие переключатели бизнес-логики. Их некорректная интерпретация приводит к:

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

Использование строгих валидаторов в class-validator снижает вероятность подобных ошибок за счёт явного разграничения допустимых типов и необходимости трансформации входных данных до их использования в бизнес-логике.