@Length, @MinLength, @MaxLength

Валидация длины строк — одна из базовых задач при обработке пользовательского ввода. В библиотеке Class-validator для этого предусмотрены декораторы @Length, @MinLength и @MaxLength, позволяющие декларативно задавать ограничения прямо в моделях данных.


@Length: фиксирование диапазона длины строки

Декоратор @Length используется для задания одновременно минимальной и максимальной длины строки. Он применяется к свойствам класса и проверяет, что длина значения находится в заданных пределах включительно.

Синтаксис

@Length(min: number, max: number, validationOptions?: ValidationOptions)
  • min — минимально допустимая длина строки
  • max — максимально допустимая длина строки
  • validationOptions — дополнительные параметры валидации (сообщения, группы и т.д.)

Базовое использование

import { Length } from "class-validator";

class CreateUserDto {
  @Length(3, 20)
  username: string;
}

В данном примере:

  • строка username должна содержать не менее 3 символов
  • и не более 20 символов

Пользовательское сообщение об ошибке

import { Length } from "class-validator";

class CreateUserDto {
  @Length(3, 20, {
    message: "Имя пользователя должно быть от 3 до 20 символов",
  })
  username: string;
}

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

  • пробелы учитываются как символы
  • пустая строка ("") не проходит валидацию
  • null и undefined игнорируются, если не используются дополнительные декораторы вроде @IsNotEmpty

@MinLength: минимальная длина строки

Декоратор @MinLength применяется, когда необходимо задать только нижнюю границу длины строки без ограничения сверху.

Синтаксис

@MinLength(min: number, validationOptions?: ValidationOptions)
  • min — минимальное количество символов

Пример использования

import { MinLength } from "class-validator";

class ChangePasswordDto {
  @MinLength(8)
  password: string;
}

Здесь пароль должен содержать не менее 8 символов.


Комбинация с другими декораторами

@MinLength часто используется вместе с @IsNotEmpty, чтобы исключить пустые значения:

import { MinLength, IsNotEmpty } from "class-validator";

class ChangePasswordDto {
  @IsNotEmpty()
  @MinLength(8)
  password: string;
}

Пользовательское сообщение

import { MinLength } from "class-validator";

class ChangePasswordDto {
  @MinLength(8, {
    message: "Пароль должен содержать минимум 8 символов",
  })
  password: string;
}

@MaxLength: ограничение максимальной длины строки

Декоратор @MaxLength задаёт верхнюю границу длины строки. Он используется, когда необходимо ограничить размер входных данных, например, для полей базы данных или UI-ограничений.

Синтаксис

@MaxLength(max: number, validationOptions?: ValidationOptions)
  • max — максимальное допустимое количество символов

Базовый пример

import { MaxLength } from "class-validator";

class CreateCommentDto {
  @MaxLength(200)
  text: string;
}

Поле text не может превышать 200 символов.


Использование с сообщением

import { MaxLength } from "class-validator";

class CreateCommentDto {
  @MaxLength(200, {
    message: "Комментарий не должен превышать 200 символов",
  })
  text: string;
}

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

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

Примеры ситуаций:

  • 12345 (number) — может быть преобразовано или отклонено в зависимости от class-transformer
  • null — игнорируется, если не добавлен @IsNotEmpty
  • undefined — игнорируется
  • "" — считается строкой длины 0 и проверяется

Совместное использование @MinLength и @MaxLength

Когда требуется ограничить строку только сверху или снизу, используется комбинация двух декораторов.

Пример ограничения диапазона через раздельные декораторы

import { MinLength, MaxLength } from "class-validator";

class UpdateTitleDto {
  @MinLength(5)
  @MaxLength(100)
  title: string;
}

Такой подход функционально эквивалентен @Length(5, 100), но может быть удобнее при динамическом построении правил.


Взаимодействие с @IsOptional

При использовании @IsOptional проверки длины не выполняются, если значение отсутствует.

import { IsOptional, MinLength, MaxLength } from "class-validator";

class UpdateProfileDto {
  @IsOptional()
  @MinLength(2)
  @MaxLength(30)
  nickname?: string;
}

Поведение:

  • если nickname не передан — валидация пропускается
  • если передан — применяются ограничения длины

Влияние трансформации данных

При использовании class-transformer входные данные могут изменяться до валидации.

import { Transform } from "class-transformer";
import { Length } from "class-validator";

class UserDto {
  @Transform(({ value }) => value?.trim())
  @Length(3, 20)
  username: string;
}

Здесь:

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

Типичные ошибки при использовании ограничений длины

Игнорирование пробелов

@MinLength(3)
username: string;

Строка " " проходит как длина 3, хотя фактически содержит только пробелы.

Решение — комбинировать с трансформацией или дополнительной проверкой:

@Transform(({ value }) => value?.trim())
@MinLength(3)
username: string;

Неправильное ожидание обработки null

@MinLength(5)
password: string;

null не всегда считается ошибкой, если не добавлен @IsNotEmpty.


Конфликт бизнес-логики и DTO-валидации

Иногда ограничения длины дублируют ограничения базы данных. Например:

  • VARCHAR(255) в базе
  • @MaxLength(255) в DTO

Несоответствие приводит к ошибкам на уровне persistence слоя, если DTO не синхронизирован с схемой.


Поведение сообщений об ошибках

При нарушении ограничений длины возвращается объект ошибки валидации следующего вида:

{
  "property": "username",
  "constraints": {
    "length": "username must be longer than or equal to 3 and shorter than or equal to 20 characters"
  }
}

При кастомизации сообщения ключ length заменяется на текст, заданный в message.


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

Проверка кодов и идентификаторов фиксированной длины

@Length(6, 6)
code: string;

Используется для:

  • OTP-кодов
  • коротких идентификаторов
  • PIN-кодов

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

@MaxLength(500)
description: string;

Применяется для:

  • описаний товаров
  • комментариев
  • постов

Жёсткое ограничение ввода

@Length(8, 8)
serialNumber: string;

Используется для строго фиксированных форматов данных, когда длина является частью спецификации.