Frontend Academy · Урок

Декораторы и метаданные

Включайте экспериментальные декораторы, создавайте декораторы классов, методов и свойств и используйте reflect-metadata в шаблонах внедрения зависимостей

Урок 2 из 414 шагов

«Декораторы и метаданные» — бесплатный урок Frontend Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

Что такое декораторы

Декораторы — это функции, которые во время определения изменяют классы, методы, свойства или параметры. Они широко используются в Angular, NestJS, TypeORM и MobX на основе классов.

Синтаксис декораторов

Добавьте @DecoratorName перед классом, методом, свойством или параметром. Функция декоратора выполняется при определении класса.

@Component({ selector: 'app-root' })
export class AppComponent {
  @Input() title: string;

  @HostListener('click')
  onClick() {
    console.log('clicked');
  }
}

Включение декораторов

Включите экспериментальный флаг в tsconfig.json. Новые декораторы ECMAScript Stage 3 (TypeScript 5.0 и новее) не требуют этого флага, но имеют другую семантику.

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Декоратор класса

Получает конструктор в качестве аргумента. Может заменить, обернуть или расширить класс.

function Singleton<T extends { new (...a: any[]): {} }>(target: T) {
  let instance: T;
  return class extends target {
    constructor(...args: any[]) {
      if (!instance) instance = new target(...args) as T;
      return instance;
    }
  };
}

@Singleton
class Logger { /* ... */ }

Декоратор метода

Получает (цель, ключ, дескриптор). Может обернуть метод, например для журналирования вызовов.

function Log(target: any, key: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`[${key}]`, args);
    return original.apply(this, args);
  };
}

class Service {
  @Log
  greet(name: string) { return `Hello ${name}`; }
}

Декоратор свойства

Получает (цель, ключ). Часто используется вместе с reflect-metadata для регистрации сведений о свойстве.

function Required(target: any, key: string) {
  const existing = Reflect.getMetadata('required', target) || [];
  Reflect.defineMetadata('required', [...existing, key], target);
}

class User {
  @Required name: string;
  @Required email: string;
}

Декоратор параметра

Получает (цель, ключ, parameterIndex). Используется для внедрения зависимостей: фиксирует, каким параметрам нужны какие сервисы.

function Inject(token: string) {
  return function (target: any, key: string, index: number) {
    const existing = Reflect.getMetadata('inject', target, key) || {};
    existing[index] = token;
    Reflect.defineMetadata('inject', existing, target, key);
  };
}

class UserService {
  constructor(@Inject('Database') db: Database) {}
}

reflect-metadata

reflect-metadata — это полифил, позволяющий декораторам читать и записывать метаданные классов. Он необходим для DI в Angular и многих ORM.

npm install reflect-metadata

// main.ts (entry point):
import 'reflect-metadata';

import { Reflect } from 'reflect-metadata';
Reflect.defineMetadata('key', 'value', target);
Reflect.getMetadata('key', target); // 'value'

Фабрики декораторов

Фабрика возвращает декоратор и используется для передачи аргументов.

function Component(config: { selector: string }) {
  return function (target: any) {
    target.selector = config.selector;
  };
}

@Component({ selector: 'app-root' })
class AppComponent {}

Пример проверки данных

Объедините декораторы свойств с функцией validate(), чтобы создать небольшую библиотеку проверки данных.

// Decorator records that a field is required:
function Required(target: any, key: string) {
  const fields = Reflect.getMetadata('required', target) || [];
  Reflect.defineMetadata('required', [...fields, key], target);
}

class User {
  @Required name!: string;
  @Required email!: string;
}

function validate(obj: any): string[] {
  const required: string[] = Reflect.getMetadata('required', obj) || [];
  return required.filter(k => obj[k] == null);
}

Декораторы Stage 3 (TC39)

Стандартизированные декораторы (TS 5.0 и новее, поддерживаются в Node 22 и новее за флагом) имеют другую сигнатуру. Им не нужны экспериментальный флаг и reflect-metadata.

Когда использовать декораторы

Используйте декораторы там, где их предоставляет фреймворк: в Angular, NestJS и TypeORM. Не создавайте собственные декораторы в обычном фронтенд-коде: они усложняют код и привязывают его к определённому поведению среды выполнения.

Быстрая проверка

Какие флаги tsconfig необходимо включить, чтобы использовать устаревшие (экспериментальные) декораторы с отражением метаданных?

Итоги: декораторы

Декораторы изменяют классы, методы, свойства и параметры во время определения. Включите experimentalDecorators и emitDecoratorMetadata. Сигнатуры декораторов класса, метода, свойства и параметра различаются. reflect-metadata хранит метаданные, а фабрики передают аргументы. Декораторы широко используются в Angular, NestJS и TypeORM. Декораторы Stage 3 (TS 5 и новее) — будущее и не требуют флагов.

Можно начать бесплатно

Изучай HTML с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
41
Уроки
163

Часто задаваемые вопросы

Урок «Декораторы и метаданные» бесплатный?

Да — полный текст урока «Декораторы и метаданные» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.

Чему я научусь в уроке «Декораторы и метаданные»?

Включайте экспериментальные декораторы, создавайте декораторы классов, методов и свойств и используйте reflect-metadata в шаблонах внедрения зависимостей Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Frontend Academy?

Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Декораторы и метаданные»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Frontend Academy?

Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Типы шаблонных литералов
  2. Декораторы и метаданные
  3. TypeScript с React: обобщения FC и хуки
  4. Строгий режим и устранение any
← Назад к Frontend Academy