@IsString

Декоратор @IsString относится к базовым валидаторам библиотеки class-validator и предназначен для проверки того, что значение свойства является строкой в строгом смысле JavaScript.


Проверка, выполняемая @IsString, опирается на строгое сравнение типа значения. Допустимыми считаются только значения, удовлетворяющие следующим условиям:

  • значение имеет тип string (примитив);
  • значение не является числом, булевым типом, объектом или массивом;
  • значение не является String-объектом (new String()), так как это объект, а не примитив.

Таким образом, проверка эквивалентна внутренней логике:

  • typeof value === 'string'

Любые попытки передать:

  • числа (123)
  • булевы значения (true, false)
  • массивы (["a"])
  • объекты ({ text: "a" })
  • null или undefined

приводят к ошибке валидации.


Базовое применение

Декоратор применяется непосредственно к свойствам классов DTO:

import { IsString } from 'class-validator';

class CreateUserDto {
  @IsString()
  username: string;
}

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


Поведение при пустых значениях

@IsString не выполняет проверку на обязательность поля. Это важный аспект архитектуры class-validator:

  • @IsString проверяет только тип;
  • за обязательность отвечает @IsNotEmpty, @IsDefined или отсутствие @IsOptional.

Пример:

import { IsString, IsNotEmpty } from 'class-validator';

class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  username: string;
}

В данном случае:

  • @IsString гарантирует тип string;
  • @IsNotEmpty запрещает пустую строку "".

Отличие строки от String-объекта

JavaScript допускает создание строк через конструктор:

new String('text')

Однако это объект, а не примитив. @IsString отклоняет такие значения, поскольку проверка основана на строгом типе.

Это поведение предотвращает скрытые ошибки, связанные с:

  • неожиданным типом данных в рантайме;
  • сериализацией объектов вместо строк;
  • проблемами при сравнении значений.

Работа в связке с преобразованием типов

В реальных приложениях данные часто приходят из HTTP-запросов как строки или как any. В связке с class-transformer можно включать автоматическое преобразование:

import { Type } from 'class-transformer';
import { IsString } from 'class-validator';

class UpdateDto {
  @Type(() => String)
  @IsString()
  id: string;
}

@Type(() => String) не изменяет поведение @IsString, но может привести входные данные к строковому виду, если это возможно.


Поведение с массивами и параметр each

При работе с массивами @IsString можно применять в двух режимах:

Проверка одного значения

@IsString()
name: string;

Проверка элементов массива

import { IsString } from 'class-validator';

class CreateDto {
  @IsString({ each: true })
  tags: string[];
}

В этом случае валидатор проверяет каждый элемент массива отдельно.

Если хотя бы один элемент не является строкой, весь массив считается невалидным.


Совместимость с другими декораторами

@IsString часто комбинируется с другими валидаторами для построения строгих контрактов данных.

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

import { IsString, IsNotEmpty, Length } from 'class-validator';

class CreateProductDto {
  @IsString()
  @IsNotEmpty()
  @Length(3, 50)
  title: string;
}

Здесь формируется цепочка проверок:

  • тип должен быть строкой;
  • строка не должна быть пустой;
  • длина ограничена диапазоном.

Поведение при undefined и null

@IsString сам по себе не считает undefined или null валидными строками. Однако поведение зависит от дополнительных декораторов:

  • без @IsOptional значение undefined приводит к ошибке;
  • с @IsOptional поле может отсутствовать без нарушения валидации.
import { IsString, IsOptional } from 'class-validator';

class UpdateDto {
  @IsOptional()
  @IsString()
  nickname?: string;
}

Типичные причины ошибок валидации

На практике наиболее частые причины, по которым @IsString отклоняет данные:

  • JSON приходит с числом вместо строки:

    { "name": 123 }
  • значение приходит из формы и не преобразовано;

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

  • null используется как значение по умолчанию;

  • отсутствует трансформация входных данных в DTO.


Особенности в NestJS контексте

При использовании в NestJS с ValidationPipe поведение @IsString становится частью пайплайна обработки запроса:

  • входные данные десериализуются в DTO;
  • выполняется проверка типов;
  • при ошибке возвращается исключение BadRequestException.

Важно, что @IsString не выполняет приведение типов автоматически. Без transform: true данные остаются в исходном виде.


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

@IsString не учитывает:

  • содержимое строки (пустота, пробелы, формат);
  • Unicode-валидность;
  • минимальную или максимальную длину;
  • контекст использования строки (URL, email, JSON и т.д.).

Его задача ограничена одним уровнем абстракции — проверкой примитивного типа.


Поведение валидации в цепочках

При комбинировании нескольких декораторов порядок влияет только на логическую читаемость, но не на механизм выполнения. Все валидаторы применяются независимо:

@IsOptional()
@IsString()
@Length(5, 20)
value?: string;

Результат формируется как набор ошибок по всем несоответствиям.


Использование в доменных моделях DTO

В строгих API-слоях @IsString выступает как базовый контракт данных:

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