Dekoratory w TypeScript

Dekoratory w TypeScript

Ten artykuł wyjaśnia dekoratory w TypeScript.

YouTube Video

Dekoratory w TypeScript

Dekoratory w TypeScript to mechanizm pozwalający na dodanie dodatkowej funkcjonalności lub zachowania do klas, metod, akcesorów, właściwości lub parametrów. Dekoratory są potężnym narzędziem zwiększającym czytelność i wielokrotne użycie kodu.

Podstawy dekoratorów

Dekorator to funkcja, która wprowadza dodatkową funkcjonalność do klasy lub jej członków. Dekoratory zostały wprowadzone w TypeScript 1.5 i zaproponowane jako standard ECMAScript.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • Aby korzystać z dekoratorów, należy włączyć opcję experimentalDecorators w pliku tsconfig.json.

Rodzaje dekoratorów

W TypeScript można używać następujących pięciu dekoratorów.

  • Dekorator klasy Dekorator zastosowany do klasy.
  • Dekorator metody Dekorator zastosowany do metody klasy.
  • Dekorator akcesora Dekorator zastosowany do gettera lub settera właściwości klasy.
  • Dekorator właściwości Dekorator zastosowany do właściwości klasy.
  • Dekorator parametru Dekorator zastosowany do parametru metody.

Dekorator klasy

Dekoratory klasy to dekoratory stosowane do klas. Dekoratory klasy są zapisywane tuż nad definicją klasy i mają dostęp do konstruktora klasy. Są one głównie używane do zmiany zachowania klasy lub dodania metadanych.

 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

W tym przykładzie dekorator Logger jest stosowany do klasy, a podczas inicjalizacji klasy wyświetlana jest wiadomość w konsoli.

Dekorator metody

Dekoratory metody są stosowane do metod klasy i mogą zmieniać wywołania metod oraz ich zachowanie. Dekorator metody przyjmuje trzy argumenty.

  1. Prototyp klasy
  2. Nazwa metody
  3. Deskryptor właściwości metody
 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)

W tym przykładzie dekorator LogExecutionTime jest zastosowany do metody, a czas wykonania metody jest rejestrowany.

Dekorator Akcesora

Dekoratory akcesorów są stosowane do getter lub setter właściwości klasy. Są przydatne do dodawania zachowania podczas zmiany wartości właściwości.

 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

W tym przykładzie dekorator dostępatorów jest używany do rejestrowania wyjścia, gdy wywoływane są getter i setter.

Dekorator Właściwości

Dekoratory właściwości są stosowane do właściwości klasy, ale nie mogą bezpośrednio zmieniać wartości lub zachowania właściwości. Są używane do uzyskiwania metadanych właściwości.

 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'

W tym przykładzie dekorator Readonly jest zastosowany do właściwości title, i właściwość ta staje się tylko do odczytu.

Dekorator Parametru

Dekoratory parametrów są stosowane do parametrów metody. Zazwyczaj są stosowane do przechowywania metadanych lub walidacji parametrów. Dekoratory przyjmują trzy argumenty.

  1. Prototyp klasy
  2. Nazwa metody
  3. Indeks Parametru
 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.

W tym przykładzie dekorator LogParameter jest zastosowany do pierwszego parametru metody greet, a po wywołaniu metody rejestruje, że parametr jest dekorowany.

Praktyczne Przykłady Dekoratorów

Dekoratory są szeroko stosowane w frameworkach takich jak Angular, szczególnie w kontekście wstrzykiwania zależności i definiowania metadanych. Na przykład użyj dekoratora @Component do definiowania komponentów Angular, jak w poniższym przykładzie.

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

Dekoratory są często stosowane jako kluczowe elementy frameworków i bibliotek, pomagając utrzymać kod zwarty i przejrzysty.

Podsumowanie Dekoratorów

Dekoratory TypeScript to potężne narzędzia, które elastycznie dodają funkcjonalność do klas, metod i właściwości. Używanie niestandardowych dekoratorów poprawia utrzymanie i wielokrotne użycie kodu, umożliwiając dalszą abstrakcję. Dekoratory odgrywają ważną rolę w frameworkach takich jak Angular i NestJS, a ich zrozumienie pomaga w dogłębnym zrozumieniu, jak te frameworki działają.

Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.

YouTube Video