В типичных сценариях работы с входными данными различного
происхождения возникает необходимость не только проверять их
корректность, но и приводить к ожидаемой структуре. В экосистеме
JavaScript эта задача решается связкой двух подходов: валидации через
class-validator и трансформации через
class-transformer. Их совместное использование формирует
единый конвейер обработки данных, где сырые значения последовательно
преобразуются в типизированные объекты и проходят проверку
бизнес-правил.
Механизм обработки данных строится на двух независимых этапах:
Такое разделение позволяет изолировать задачи:
Это особенно важно при работе с внешними источниками данных, где типизация отсутствует или нарушена.
Базовым инструментом трансформации выступает
plainToInstance из class-transformer. Он
преобразует обычные объекты в экземпляры классов, что делает доступными
декораторы class-validator.
import { plainToInstance } from 'class-transformer';
class UserDto {
name;
age;
}
const input = { name: 'Alex', age: '25' };
const instance = plainToInstance(UserDto, input);
Без этапа трансформации валидаторы не получают метаданных класса, что делает проверку невозможной или неполной.
После приведения данных к экземпляру класса применяется функция
validate или validateSync:
import { validate } from 'class-validator';
const errors = await validate(instance);
Декораторы внутри класса определяют правила проверки:
import { IsString, IsInt, Min } from 'class-validator';
class UserDto {
@IsString()
name;
@IsInt()
@Min(18)
age;
}
Входные данные часто содержат строки вместо чисел, особенно при работе с HTTP-запросами. Например:
const input = { name: 'Alex', age: '25' };
Без трансформации поле age остаётся строкой, что
приводит к ошибкам валидации при использовании
@IsInt().
Для устранения подобных проблем используется
class-transformer с включённой опцией приведения типов:
import { plainToInstance } from 'class-transformer';
const instance = plainToInstance(UserDto, input, {
enableImplicitConversion: true
});
При таком подходе строковое значение "25" автоматически
преобразуется в число 25.
При работе с вложенными объектами требуется явное указание типов:
import { Type } from 'class-transformer';
import { ValidateNested } from 'class-validator';
class Profile {
@IsString()
city;
}
class UserDto {
@IsString()
name;
@ValidateNested()
@Type(() => Profile)
profile;
}
Без декоратора @Type вложенная структура остаётся
обычным объектом, и валидация вложенных полей не выполняется.
Массивы требуют комбинации @Type и
@ValidateNested:
class Role {
@IsString()
title;
}
class UserDto {
@ValidateNested({ each: true })
@Type(() => Role)
roles;
}
Ключевой момент заключается в параметре each: true,
который активирует проверку каждого элемента массива отдельно.
Корректный порядок обработки данных критичен для стабильности системы:
plainToInstancevalidateНарушение последовательности приводит к некорректной интерпретации типов и частичным ошибкам валидации.
Для сложных случаев применяются пользовательские трансформации через
@Transform:
import { Transform } from 'class-transformer';
class UserDto {
@Transform(({ value }) => value.trim())
name;
}
Такой механизм позволяет очищать, нормализовать и преобразовывать данные до этапа валидации.
Трансформация часто используется для приведения данных к форме, удобной для дальнейшей обработки:
class EventDto {
@Transform(({ value }) => new Date(value))
date;
}
После преобразования валидатор может использовать
@IsDate() или другие типы проверки.
При совместной работе трансформации и валидации важно учитывать сценарии:
undefinedЭто требует явного контроля допустимых значений через декораторы:
import { IsOptional } from 'class-validator';
class UserDto {
@IsOptional()
@IsInt()
age;
}
При больших объёмах данных важную роль играет производительность. Оптимизация достигается через:
excludeExtraneousValues в
трансформации@ValidateNestedplainToInstance(UserDto, input, {
excludeExtraneousValues: true
});
Эффективная интеграция достигается при строгом соблюдении единой модели данных:
Такой подход устраняет необходимость ручных проверок типов и снижает количество ошибок, возникающих на границах системы.