Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое декоратор в TypeScript?
В TypeScript декоратор — это специальный вид функции, которая может быть прикреплена к классам, методам, свойствам, параметрам методов или accessors (геттерам/сеттерам) для изменения или расширения их поведения без прямого изменения исходного кода. Декораторы представляют собой форму метапрограммирования, позволяющую добавлять функциональность через аннотации. Они являются экспериментальной функцией (на момент ECMAScript 5), но активно используются в фреймворках, таких как Angular, для реализации таких паттернов, как Dependency Injection, Validation или Logging.
Как работают декораторы?
Декоратор — это функция, которая вызывается во время инициализации или компиляции целевого элемента (например, класса). Он принимает определенные аргументы, зависящие от типа декорируемого элемента, и может возвращать значение для его замены или модификации. В TypeScript декораторы применяются с помощью синтаксиса @decoratorName, помещаемого непосредственно перед объявлением элемента.
function logDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(`Декорирован метод: ${key}`);
}
class ExampleClass {
@logDecorator
exampleMethod() {
console.log("Выполнение метода");
}
}
Типы декораторов и их аргументы
TypeScript поддерживает несколько типов декораторов, каждый со своим набором параметров:
-
Декоратор класса — применяется к классу. Принимает один аргумент: конструктор класса.
function sealClass(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); } @sealClass class SealedClass { // Класс теперь "запечатан" } -
Декоратор метода — применяется к методу класса. Принимает три аргумента:
* `target` — конструктор класса для статических методов или прототип класса для обычных методов.
* `key` — имя метода.
* `descriptor` — PropertyDescriptor объекта (содержит значения `value`, `writable`, `enumerable`, `configurable`). Декоратор может возвращать новый PropertyDescriptor для замены исходного.
```typescript
function readonlyMethod(target: any, key: string, descriptor: PropertyDescriptor) {
descriptor.writable = false; // Запрещает изменение метода
}
class MyClass {
@readonlyMethod
importantMethod() { return "Неизменяемый метод"; }
}
```
3. Декоратор свойства — применяется к свойству класса. Принимает два аргумента:
* `target` — конструктор класса для статических свойств или прототип класса для обычных свойств.
* `key` — имя свойства.
```typescript
function trackPropertyChange(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get: () => value,
set: (newVal) => {
console.log(`Свойство ${key} изменено на ${newVal}`);
value = newVal;
},
enumerable: true,
configurable: true
});
}
class User {
@trackPropertyChange
name: string = "Иван";
}
```
4. Декоратор параметра метода — применяется к параметру метода. Принимает три аргумента:
* `target` — конструктор класса или прототип.
* `key` — имя метода.
* `index` — индекс параметра в списке аргументов метода.
```typescript
function validateParameter(target: any, key: string, index: number) {
// Логика валидации параметра по индексу
}
class Calculator {
add(@validateParameter a: number, @validateParameter b: number) {
return a + b;
}
}
```
5. Декоратор Accessor (геттера/сеттера) — работает аналогично декоратору метода, но применяется к get/set функциям.
Порядок применения декораторов
Декораторы выполняются в определенном порядке при инициализации класса:
- Декораторы параметров → Декораторы методов/accessors/свойств → Декоратор класса.
- Для одного элемента несколько декораторов применяются сверху вниз (от ближайшего к элементу к дальнему), но их логика выполнения может быть более сложной.
Практическое применение и примеры
Декораторы широко используются для:
- Логирования выполнения методов.
- Валидации входных параметров или свойств.
- Авторизации и проверки доступа к методам.
- Измерения производительности (например, времени выполнения).
- Модификации поведения (например, превращение метода в асинхронный).
- Реализации AOP (Aspect-Oriented Programming) — отделения сквозной функциональности от бизнес-логики.
Пример декоратора для измерения времени выполнения метода:
function measureTime(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const start = performance.now();
const result = originalMethod.apply(this, args);
const end = performance.now();
console.log(`Метод ${key} выполнен за ${end - start} мс`);
return result;
};
return descriptor;
}
class Service {
@measureTime
heavyCalculation() {
// Длительная операция
let sum = 0;
for (let i = 0; i < 1000000; i++) sum += i;
return sum;
}
}
Важные особенности
- Декораторы в TypeScript являются экспементальной функцией, требующей включения флага
experimentalDecoratorsвtsconfig.json. - Они не изменяют исходный код класса, а модифицируют его во время компиляции или инициализации.
- Декораторы могут быть композируемыми — несколько декораторов могут быть применены к одному элементу, создавая слои функциональности.
- В будущем они могут стать частью стандарта ECMAScript (на данный момент предложение находится на стадии рассмотрения).
Декораторы предоставляют мощный инструмент для создания чистого, модульного и расширяемого кода, позволяя инкапсулировать повторяющуюся функциональность в отдельные функции-декораторы, которые легко применяются к различным элементам класса.