Декораторы в TypeScript

Декораторы в TypeScript

Эта статья объясняет декораторы в TypeScript.

YouTube Video

Декораторы в TypeScript

Декораторы в TypeScript — это механизм для добавления дополнительной функциональности или поведения к классам, методам, аксессорам, свойствам или параметрам. Декораторы являются мощным инструментом для повышения читаемости и повторного использования кода.

Основы декораторов

Декоратор — это функция, которая добавляет дополнительную функциональность классу или его элементам. Декораторы были введены в TypeScript 1.5 и также предложены для стандарта ECMAScript.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • Чтобы использовать декораторы, необходимо включить опцию experimentalDecorators в файле tsconfig.json.

Типы декораторов

В TypeScript вы можете использовать следующие пять типов декораторов.

  • Декоратор класса Декоратор, применяемый к классу.
  • Декоратор метода Декоратор, применяемый к методу класса.
  • Декоратор аксессора Декоратор, применяемый к геттеру или сеттеру свойства класса.
  • Декоратор свойства Декоратор, применяемый к свойству класса.
  • Декоратор параметра Декоратор, применяемый к параметру метода.

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

Декораторы класса — это декораторы, применяемые к классам. Декораторы класса пишутся непосредственно перед определением класса и имеют доступ к его конструктору. Они в основном используются для изменения поведения класса или добавления метаданных.

 1function Logger(constructor: Function) {
 2    console.log(`Class ${constructor.name} is being constructed`);
 3}
 4
 5@Logger
 6class Person {
 7    constructor(public name: string) {}
 8}
 9
10const person = new Person('John');
11// Output: Class Person is being constructed

В этом примере декоратор Logger применяется к классу, и сообщение отображается в консоли при инициализации класса.

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

Декораторы методов применяются к методам класса и могут изменять вызовы и поведение методов. Декоратор метода принимает три аргумента.

  1. Прототип класса
  2. Имя метода
  3. Дескриптор свойства метода
 1function LogExecutionTime(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
 2    const originalMethod = descriptor.value;
 3
 4    descriptor.value = function (...args: any[]) {
 5        console.time(propertyKey);
 6        const result = originalMethod.apply(this, args);
 7        console.timeEnd(propertyKey);
 8        return result;
 9    };
10}
11
12class MathOperations {
13  @LogExecutionTime
14  add(a: number, b: number): number {
15    return a + b;
16  }
17}
18
19const math = new MathOperations();
20math.add(2, 3);
21// Output: add: 0.000ms (execution time is displayed)

В этом примере декоратор LogExecutionTime применяется к методу, и время выполнения метода фиксируется в логах.

Декоратор доступа

Декораторы доступа применяются к getter или setter свойств класса. Они полезны для добавления поведения при изменении значений свойств.

 1function LogAccess(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
 2    const originalGet = descriptor.get;
 3    const originalSet = descriptor.set;
 4
 5    if (originalGet) {
 6        descriptor.get = function () {
 7            console.log(`Getter called for ${propertyKey}`);
 8            return originalGet.call(this);
 9        };
10    }
11
12    if (originalSet) {
13        descriptor.set = function (value: any) {
14            console.log(`Setter called for ${propertyKey} with value: ${value}`);
15            originalSet.call(this, value);
16        };
17    }
18}
19
20class Car {
21    private _speed: number = 0;
22
23    @LogAccess
24    get speed() {
25        return this._speed;
26    }
27
28    set speed(value: number) {
29        this._speed = value;
30    }
31}
32
33const car = new Car();
34car.speed = 120;               // Setter called for speed with value: 120
35console.log(car.speed);       // Getter called for speed → 120

В этом примере используется декоратор аксессора для ведения журнала вывода при вызове getter и setter.

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

Декораторы свойств применяются к свойствам класса, но не могут напрямую изменять значение или поведение свойств. Они используются для получения метаданных свойств.

 1function Readonly(target: any, propertyKey: string) {
 2    Object.defineProperty(target, propertyKey, {
 3        writable: false
 4    });
 5}
 6
 7class Book {
 8    @Readonly
 9    title: string = "TypeScript Guide";
10}
11
12const book = new Book();
13book.title = "New Title"; // Error: Cannot assign to read only property 'title'

В этом примере декоратор Readonly применяется к свойству title, делая его доступным только для чтения.

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

Декораторы параметров применяются к параметрам метода. Обычно они используются для хранения метаданных или проверки параметров. Декораторы принимают три аргумента.

  1. Прототип класса
  2. Имя метода
  3. Индекс параметра
 1function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
 2    console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} was decorated.`);
 3}
 4
 5class User {
 6    greet(@LogParameter message: string) {
 7        console.log(message);
 8    }
 9}
10
11const user = new User();
12user.greet('Hello!');
13// Output: Parameter at index 0 in method greet was decorated.

В этом примере декоратор LogParameter применяется к первому параметру метода greet, и при вызове метода фиксируется, что параметр декорирован.

Практические примеры использования декораторов

Декораторы широко используются в таких фреймворках, как Angular, особенно для внедрения зависимостей и определения метаданных. Например, используйте декоратор @Component для определения компонентов Angular, как показано ниже.

1@Component({
2    selector: 'app-root',
3    template: '<h1>Hello World</h1>',
4})
5export class AppComponent {}

Таким образом, декораторы часто используются как основные части фреймворков и библиотек, помогая сделать код лаконичным и понятным.

Итоги о декораторах

Декораторы TypeScript — это мощные инструменты, которые гибко добавляют функциональность к классам, методам и свойствам. Использование пользовательских декораторов улучшает сопровождаемость и повторное использование кода, позволяя достичь большей абстракции. Декораторы играют важную роль в таких фреймворках, как Angular и NestJS, и их понимание помогает глубже понять, как работают эти фреймворки.

Вы можете следовать этой статье, используя Visual Studio Code на нашем YouTube-канале. Пожалуйста, также посмотрите наш YouTube-канал.

YouTube Video