reflect-metadata и типы Design
Получайте типы параметров и свойств во время выполнения
«reflect-metadata и типы Design» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Метаданные отражения и типы времени разработки
До появления стандартизированных метаданных TypeScript мог генерировать информацию о типах на этапе разработки во время выполнения с помощью библиотеки метаданных отражения и флага компилятора emitDecoratorMetadata. В этом уроке рассматривается этот более старый, но всё ещё широко используемый механизм.
Включение этой возможности
Требуются две вещи: включить параметры компилятора и один раз импортировать библиотеку в точке входа программы.
// tsconfig.json
// {
// "compilerOptions": {
// "experimentalDecorators": true,
// "emitDecoratorMetadata": true
// }
// }
import "reflect-metadata";Что генерируется
При использовании emitDecoratorMetadata компилятор генерирует для декорированных членов три ключа: design:type, design:paramtypes и design:returntype. Значениями служат функции-конструкторы (например, String и Number).
Чтение типа свойства
Для декорированного свойства вызов Reflect.getMetadata("design:type", target, key) возвращает конструктор типа свойства.
import "reflect-metadata";
function track(target: any, key: string) {
const t = Reflect.getMetadata("design:type", target, key);
console.log(key, "->", t.name); // e.g. "name -> String"
}
class Person {
@track name!: string;
@track age!: number;
}Чтение типов параметров
У конструктора или метода design:paramtypes представляет собой массив конструкторов типов параметров — основу внедрения зависимостей.
function injectable(target: any) {
const params = Reflect.getMetadata("design:paramtypes", target);
console.log(params.map((p: any) => p.name)); // ["Database", "Logger"]
}
@injectable
class Service {
constructor(private db: Database, private log: Logger) {}
}Ограничения сгенерированных типов
Сохраняются только простые типы, представимые во время выполнения. Интерфейсы, объединения и обобщённые типы сводятся к Object, поскольку у них нет конструктора во время выполнения. Типы времени разработки приблизительны и не представляют полный тип TS.
Пользовательские метаданные с помощью Reflect
Вы также можете определять собственные ключи метаданных с помощью Reflect.defineMetadata, независимо от типов времени разработки.
import "reflect-metadata";
function required(target: any, key: string) {
Reflect.defineMetadata("required", true, target, key);
}
function isRequired(target: any, key: string) {
return Reflect.getMetadata("required", target, key) === true;
}Где это используется
Этот механизм лежит в основе многих распространённых платформ (NestJS, TypeORM, валидатор классов). Они читают design:type и design:paramtypes, чтобы связывать зависимости и проверять значения, не заставляя Вас повторно указывать типы.
Метаданные отражения и стандартные метаданные
Новый API Symbol.metadata является частью языка и не генерирует типы времени разработки. Библиотека метаданных отражения уникальным образом предоставляет сведения о типах, но привязана к экспериментальному режиму декораторов. Выбирайте одну модель для каждого проекта.
Порядок импорта имеет значение
import "reflect-metadata" должен выполняться один раз и до вычисления любого декорированного класса, поскольку он дополняет глобальный объект Reflect функциями работы с метаданными. Импортируйте его в самом начале файла входа.
Почему это важно
Генерация типов времени разработки позволяет платформам устранить разрыв между типами на этапе компиляции и поведением во время выполнения, что обеспечивает удобные DI и проверку данных. Знание ограничений (отсутствие интерфейсов и обобщённых типов) помогает избежать неожиданных результатов Object.
Быстрая проверка
Проверьте своё понимание библиотеки метаданных отражения.
Итоги
При использовании experimentalDecorators + emitDecoratorMetadata и раннего import "reflect-metadata" компилятор генерирует design:type и design:paramtypes как конструкторы, доступные во время выполнения. Платформы читают их для DI и проверки данных, хотя интерфейсы, объединения и обобщённые типы преобразуются в Object.
Часто задаваемые вопросы
Урок «reflect-metadata и типы Design» бесплатный?
Да — полный текст урока «reflect-metadata и типы Design» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «reflect-metadata и типы Design»?
Получайте типы параметров и свойств во время выполнения Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «reflect-metadata и типы Design»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Объяснение декораторов третьего этапа
- Метаданные декораторов
- reflect-metadata и типы Design
- Создание фреймворка декораторов