В библиотеке Class-validator числовая валидация строится на наборе специализированных декораторов, обеспечивающих проверку типа, диапазонов, знака и дополнительных ограничений. В отличие от простых проверок JavaScript, где типы могут неявно приводиться, здесь контроль основан на явной типизации DTO-классов и метаданных, формируемых декораторами.
@IsNumberБазовый декоратор для проверки числового значения:
import { IsNumber } fr om 'class-validator';
class ProductDto {
@IsNumber()
price: number;
}
@IsNumber() проверяет строгое соответствие типу
number. При этом строковые значения вроде
"123" считаются невалидными.
IsNumberOptionsДекоратор поддерживает настройки, влияющие на строгость проверки:
@IsNumber({}, { allowNaN: false, allowInfinity: false })
value: number;
allowNaN — разрешает NaNallowInfinity — разрешает Infinity и
-InfinityПример с расширенной допустимостью:
@IsNumber({}, { allowNaN: true, allowInfinity: true })
metric: number;
@IsIntДля значений без дробной части используется отдельный декоратор:
import { IsInt } from 'class-validator';
class UserDto {
@IsInt()
age: number;
}
Пример невалидных значений:
12.5"10"trueimport { IsPositive } from 'class-validator';
class PaymentDto {
@IsPositive()
amount: number;
}
Допускаются только значения строго больше 0.
import { IsNegative } from 'class-validator';
class TemperatureDto {
@IsNegative()
value: number;
}
Допускаются только значения меньше 0.
import { IsNotNegative, IsNotPositive } from 'class-validator';
class RangeDto {
@IsNotNegative()
min: number;
@IsNotPositive()
max: number;
}
IsNotNegative → >= 0IsNotPositive → <= 0@Min и @Maximport { Min } from 'class-validator';
class ScoreDto {
@Min(0)
score: number;
}
import { Max } from 'class-validator';
class ScoreDto {
@Max(100)
score: number;
}
class ProgressDto {
@Min(0)
@Max(1)
progress: number;
}
В реальных HTTP-запросах числа часто приходят как строки:
{
"price": "150"
}
Без преобразования такие значения не пройдут
@IsNumber().
Для корректной работы числовых валидаторов используется
преобразование через class-transformer.
import { Type } from 'class-transformer';
import { IsNumber } from 'class-validator';
class ProductDto {
@Type(() => Number)
@IsNumber()
price: number;
}
@Type(() => Number)number@IsNumberStringДля случаев, когда значение должно оставаться строкой, но содержать число:
import { IsNumberString } from 'class-validator';
class QueryDto {
@IsNumberString()
page: string;
}
NaN, пробелы, символы@IsNumber()
value: number;
NaN по умолчанию считается невалиднымInfinity и -Infinity также отклоняются без
опцийnull и undefined не проходят числовую
валидацию, если не используются дополнительные декораторы:
@IsOptional() — допускает отсутствие поляimport { IsOptional, IsNumber } from 'class-validator';
class FilterDto {
@IsOptional()
@IsNumber()
lim it?: number;
}
Числовые валидаторы часто комбинируются с другими ограничениями:
import { IsInt, Min, Max, IsPositive } from 'class-validator';
class RatingDto {
@IsInt()
@Min(1)
@Max(5)
rating: number;
}
или
class AccountDto {
@IsPositive()
@IsNumber()
balance: number;
}
class Dto {
@IsNumber()
value: number;
}
Вход "42" приведёт к ошибке, даже если логически
значение корректно.
@IsNumber вместо @IsIntДля идентификаторов часто требуется строгое целое число:
class ParamDto {
@IsInt()
id: number;
}
Использование @IsNumber может допустить дробные
значения, что нарушает бизнес-логику.
Отсутствие @Min и @Max приводит к тому, что
валидируется только тип, но не смысл значения:
class DiscountDto {
@IsNumber()
percent: number; // логически должен быть 0–100
}
Корректная форма:
class DiscountDto {
@Min(0)
@Max(100)
percent: number;
}
Числовые валидаторы раскрываются полноценно только в строгой DTO-модели, где:
Такой подход обеспечивает детерминированную проверку данных на уровне структуры, а не логики выполнения.