Декоратор @NotEquals в библиотеке class-validator
используется для проверки неравенства значения свойства заранее заданной
константе. Валидация выполняется по строгому сравнению (===
/ !== в терминах семантики JavaScript), что делает
поведение предсказуемым при работе с примитивами.
Основная задача — гарантировать, что значение поля не совпадает с указанным запрещённым значением. Это применяется для фильтрации недопустимых дефолтов, маркеров, системных флагов или зарезервированных значений.
Декоратор принимает одно обязательное значение — то, с чем производится сравнение.
import { NotEquals } from 'class-validator';
class UserDto {
@NotEquals('admin')
role: string;
}
В данном случае значение role не должно быть строкой
"admin". Любое другое значение проходит проверку.
@NotEquals реализует простое отрицание равенства:
value !== comparisonValuevalue === comparisonValueСравнение осуществляется без приведения типов, что критично для строгой типизации DTO-слоя.
Примеры поведения:
| Значение | Запрещённое значение | Результат |
|---|---|---|
| “user” | “admin” | проходит |
| “admin” | “admin” | ошибка |
| 1 | 1 | ошибка |
| “1” | 1 | проходит |
По умолчанию библиотека формирует стандартное сообщение, но его можно переопределить через опции:
import { NotEquals } from 'class-validator';
class ProductDto {
@NotEquals('draft', {
message: 'status не может быть draft',
})
status: string;
}
Сообщения часто используются в API-слоях для формирования читаемых ошибок валидации.
@NotEquals применяется не только к строкам, но и к
числам:
class ConfigDto {
@NotEquals(0)
retries: number;
}
В этом случае значение 0 запрещено, например, для
предотвращения отключённой логики повторных попыток.
Булевы значения часто используются как переключатели состояния:
class FeatureDto {
@NotEquals(false)
enabled: boolean;
}
Такой подход применяется, когда false является
недопустимым состоянием (например, обязательное включение
функциональности).
@NotEquals не выполняет автоматическую проверку на
наличие значения. Если свойство отсутствует, поведение зависит от
дополнительных декораторов:
import { NotEquals, IsDefined } from 'class-validator';
class ExampleDto {
@IsDefined()
@NotEquals('none')
mode: string;
}
Без @IsDefined() значение undefined может
пройти проверку, так как undefined !== 'none'.
@NotEquals часто используется в связке с другими
ограничениями:
import { NotEquals, IsString, Length } from 'class-validator';
class AccountDto {
@IsString()
@Length(3, 20)
@NotEquals('root')
username: string;
}
Такая композиция формирует более строгую бизнес-логику: имя должно быть строкой, иметь длину и не совпадать с системным идентификатором.
@NotEquals не предназначен для глубокого сравнения
структур. При применении к массивам сравнение происходит по ссылке:
class DataDto {
@NotEquals([1, 2, 3])
values: number[];
}
В этом случае проверяется не содержимое массива, а его ссылка, что делает такой подход практически бесполезным для структурных данных.
Для вложенных объектов валидатор также сравнивает ссылки:
class Inner {
x: number;
}
class Outer {
@NotEquals({ x: 1 })
data: Inner;
}
Сравнение выполняется некорректно для глубоких структур, что является важным ограничением.
Валидация через @NotEquals часто применяется для
предотвращения попадания запрещённых маркеров в систему:
class OrderDto {
@NotEquals('test')
comment: string;
}
Такие значения могут использоваться фронтендом или тестовыми окружениями, но должны блокироваться в продакшене.
Библиотека class-transformer часто используется совместно с class-validator для преобразования входных данных.
Важно учитывать, что @NotEquals работает уже после
трансформации:
import { Type } from 'class-transformer';
import { NotEquals } from 'class-validator';
class PaymentDto {
@Type(() => Number)
@NotEquals(0)
amount: number;
}
В этом примере строковое значение "0" будет
преобразовано в число 0, после чего сработает
валидация.
@NotEquals не зависит от режима строгой валидации.
Однако результат может изменяться в зависимости от предварительной
обработки данных:
"10" и 10 считаются
разнымиclass LogDto {
@NotEquals('SYSTEM')
source: string;
}
class FilterDto {
@NotEquals('all')
category: string;
}
class RetryDto {
@NotEquals(0)
delay: number;
}
Функциональность @NotEquals ограничена простыми
типами:
По сути, это инструмент для атомарных проверок.
На уровне реализации используется простой constraint, который принимает значение из декоратора и сравнивает его с текущим значением свойства:
Такая модель делает валидатор лёгким и предсказуемым.
Поведение различается в зависимости от типа:
Это накладывает ограничения на использование в сложных структурах данных.
@NotEquals редко используется как единственный
валидатор. Чаще он выступает частью набора правил, формирующих
ограничения доменной модели:
Комбинация с @IsEnum, @IsString,
@IsOptional, @ValidateIf позволяет формировать
гибкие схемы проверки входных данных без усложнения бизнес-логики.