Декоратор @IsInt из библиотеки
class-validator используется для проверки того, что
значение свойства является целым числом. Под целым числом понимается
числовой тип без дробной части, например 0, 1,
-10, 42. Значения 3.14,
2.0 (в некоторых случаях преобразования), строки и другие
типы считаются невалидными, если не применены дополнительные
преобразования.
Основная задача @IsInt — обеспечить строгую проверку
входных данных на уровне DTO (Data Transfer Object). Это особенно важно
в приложениях, где данные поступают извне: HTTP-запросы, очереди
сообщений, внешние API.
Проверка выполняется следующим образом:
numberПримеры валидных значений:
100-25Примеры невалидных значений:
10.5"10"NaNInfinityimport { IsInt } fr om 'class-validator';
class CreateUserDto {
@IsInt()
age: number;
}
В этом примере поле age будет считаться валидным только
если оно является целым числом.
В реальных приложениях входные данные часто приходят в виде строк, даже если они представляют числа. Например, HTTP-запрос:
{
"age": "25"
}
Без преобразования class-validator получит строку, а не
число, и проверка @IsInt не пройдет.
Для решения используется class-transformer:
import { Type } from 'class-transformer';
import { IsInt } from 'class-validator';
class CreateUserDto {
@Type(() => Number)
@IsInt()
age: number;
}
Здесь происходит явное преобразование строки "25" в
число 25 перед валидацией.
@IsInt опирается на строгую проверку типа и значения.
Внутренне библиотека проверяет:
typeof value === "number")Number.isInteger(value))Таким образом, логика эквивалентна:
Number.isInteger(value)
Это означает, что даже числа вида 5.0 в JavaScript уже
являются 5, и считаются допустимыми, поскольку фактически
не содержат дробной части.
Частая ошибка — использование @IsInt там, где требуется
@IsNumber.
@IsInt — строго целые числа@IsNumber — любые числа (включая дробные)import { IsNumber, IsInt } from 'class-validator';
class ExampleDto {
@IsNumber()
price: number;
@IsInt()
quantity: number;
}
В этом примере:
price может быть 10.99quantity должен быть строго 10,
11, 12 и т.д.По умолчанию библиотека возвращает стандартное сообщение об ошибке:
age must be an integer number
Можно переопределить сообщение через
ValidationOptions:
import { IsInt, ValidationOptions } from 'class-validator';
class CreateUserDto {
@IsInt({ message: 'Возраст должен быть целым числом' })
age: number;
}
В экосистеме NestJS @IsInt применяется внутри
DTO-классов, которые проходят через ValidationPipe.
import { IsInt } from 'class-validator';
export class UpdateProductDto {
@IsInt()
stock: number;
}
Контроллер:
@Post()
create(@Body() dto: UpdateProductDto) {
return dto;
}
При включённом ValidationPipe:
app.useGlobalPipes(new ValidationPipe({ transform: true }));
входные данные автоматически проверяются и при необходимости преобразуются.
age: "20"
Результат: невалидно, если не используется
@Type(() => Number).
age: 20.1
Результат: невалидно.
age: NaN
Результат: невалидно, поскольку Number.isInteger(NaN)
возвращает false.
age: Infinity
Результат: невалидно.
Валидация выполняется после преобразования типов (если оно включено). Это критически важно, поскольку порядок влияет на результат:
class-transformer преобразует данныеclass-validator выполняет проверкуБез преобразования большинство входных значений из HTTP окажутся
строками и не пройдут @IsInt.
@IsInt часто используется совместно с другими
валидаторами для уточнения ограничений.
import { IsInt, Min, Max } from 'class-validator';
class PaginationDto {
@IsInt()
@Min(1)
@Max(100)
lim it: number;
}
В этом случае:
@IsInt()
age: number;
Если приходит "25", проверка провалится.
@IsInt не выполняет округление. Значение либо проходит
проверку, либо нет.
age: "10"
Это не считается числом, даже если строка содержит числовой символ.
При включённой строгой валидации и отключённом преобразовании:
Это делает @IsInt особенно полезным для API, где важна
предсказуемость входных данных.
@IsInt применяется только к конкретному полю. Для
массивов требуется дополнительная комбинация декораторов:
import { IsInt, IsArray } fr om 'class-validator';
class NumbersDto {
@IsArray()
@IsInt({ each: true })
values: number[];
}
Здесь параметр each: true заставляет валидатор проверять
каждый элемент массива отдельно.
@IsInt часто используется для:
id, userId,
productId)count,
quantity)page, limit)Типичная структура DTO:
class GetItemsDto {
@IsInt()
page: number;
@IsInt()
lim it: number;
}
Такая модель позволяет строго контролировать параметры запроса и исключать некорректные данные на раннем этапе обработки.