Для работы с декораторами в TypeScript требуется включение ряда компиляторных возможностей, которые в стандартной конфигурации отключены из-за экспериментального статуса этой функциональности. Декораторы лежат в основе таких библиотек, как Class-validator, поскольку позволяют декларативно описывать правила валидации прямо в классах и их свойствах.
Декораторы в TypeScript представляют собой функции, которые применяются к классам, методам, свойствам или параметрам. Их основная задача — расширение поведения без изменения исходной логики.
В контексте валидации данных декораторы позволяют:
Библиотека Class-validator активно использует декораторы вида
@IsString, @IsInt, @Length,
@IsEmail, превращая классы в самодокументируемые схемы
валидации.
По умолчанию TypeScript не активирует декораторы, поскольку их спецификация долгое время оставалась в стадии предложения ECMAScript. Для их включения необходимо изменить конфигурацию компилятора.
Основной файл настройки — tsconfig.json.
Минимальная конфигурация для работы с декораторами выглядит следующим образом:
{
"compilerOptions": {
"target": "ES2017",
"module": "commonjs",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true
}
}
Параметр experimentalDecorators включает поддержку
синтаксиса декораторов. Без него любая попытка использовать
@Decorator() приведёт к ошибке компиляции.
Этот флаг активирует трансформацию кода на этапе компиляции, позволяя TypeScript преобразовывать декларативные конструкции в обычные функции JavaScript.
Флаг emitDecoratorMetadata отвечает за генерацию
дополнительной метаинформации о типах в рантайме. Он используется
совместно с библиотекой рефлексии и позволяет получать информацию о
типах свойств и параметров классов.
Эта возможность критически важна для Class-validator, поскольку многие валидаторы зависят от типа данных, например строка, число или массив.
Без включённой метаинформации декораторы теряют часть возможностей автоматического определения типов.
Для работы механизма метаданных требуется подключение полифила:
npm install reflect-metadata
После установки необходимо подключить его в точке входа приложения:
import "reflect-metadata";
Эта строка должна быть выполнена до использования любых декораторов.
Библиотека Class-validator использует API
Reflect.defineMetadata и Reflect.getMetadata,
которые предоставляются именно этим пакетом.
Без подключения reflect-metadata метаданные не будут
сохраняться, и автоматическая валидация типов перестанет работать
корректно.
При включённом emitDecoratorMetadata TypeScript
добавляет в скомпилированный JavaScript вызовы, которые сохраняют
информацию о типах:
Пример:
class User {
name: string;
}
После компиляции с метаданными TypeScript добавляет скрытую
информацию о том, что name имеет тип
String.
Эти данные затем используются валидаторами для автоматического применения правил в Class-validator.
Декораторы в TypeScript имеют ряд архитектурных ограничений, которые необходимо учитывать при настройке среды:
Декораторы применяются в строго определённом порядке:
Это важно при комбинировании нескольких правил валидации, так как порядок влияет на итоговое поведение.
Декораторы не работают с фактическими значениями в момент компиляции. Они лишь модифицируют метаданные и поведение на уровне определения класса.
Фактическая валидация выполняется в рантайме, когда создаётся экземпляр объекта.
TypeScript-типизация и система декораторов существуют параллельно. Типы используются на этапе компиляции, тогда как декораторы работают в рантайме.
Это означает:
string не гарантирует валидацию без
декоратора;@IsString() обеспечивает проверку в
рантайме;emitDecoratorMetadata связывает оба уровня через
метаданные.В Class-validator это позволяет строить гибридную модель, где типы и декораторы дополняют друг друга.
После настройки tsconfig.json и подключения
reflect-metadata процесс компиляции не требует
дополнительных шагов.
Пример структуры запуска:
npx tsc
node dist/index.js
При использовании ts-node:
npx ts-node src/index.ts
Важно, чтобы импорт reflect-metadata выполнялся до
загрузки модулей, использующих декораторы.
Ошибка вида:
Experimental support for decorators is a feature that is subject to change
означает, что experimentalDecorators не включён.
Если валидаторы из Class-validator не определяют типы корректно,
причина обычно в отключённом emitDecoratorMetadata.
Ошибка выполнения:
Reflect.getMetadata is not a function
указывает на отсутствие импорта reflect-metadata.
Валидационные декораторы применяются непосредственно к свойствам классов:
import { IsString, Length } from "class-validator";
class CreateUserDto {
@IsString()
@Length(2, 20)
name: string;
}
Работа этой конструкции возможна только при корректной настройке TypeScript, поскольку:
@IsString() регистрирует правило через метаданные;name: string используется для вывода типа;reflect-metadata сохраняет информацию в рантайме.При компиляции TypeScript преобразует декораторы в вызовы функций следующего вида:
Таким образом, библиотека Class-validator не зависит от TypeScript напрямую, а работает через стандартизированный слой метаданных.
В новых версиях TypeScript ведётся переход к новой спецификации декораторов ECMAScript, отличающейся от legacy-реализации.
Однако большинство экосистемы, включая Class-validator, по-прежнему использует классическую модель, основанную на:
experimentalDecorators: truereflect-metadataПереход на новую модель требует пересмотра архитектуры библиотек и пока не является стандартом валидационных решений.
Корректная настройка TypeScript обеспечивает:
В связке с Class-validator это формирует основу для построения типобезопасных схем данных, где структура классов определяет правила проверки ещё до выполнения программы.