Dekoratorer i TypeScript

Dekoratorer i TypeScript

Den här artikeln förklarar dekoratorer i TypeScript.

YouTube Video

Dekoratorer i TypeScript

TypeScript-dekoratorer är en mekanism för att lägga till ytterligare funktionalitet eller beteende till klasser, metoder, accessorer, egenskaper eller parametrar. Dekoratorer är ett kraftfullt verktyg för att förbättra koden läsbarhet och återanvändbarhet.

Grunderna i dekoratorer

En dekorator är en funktion som tillför ytterligare funktionalitet till en klass eller dess medlemmar. Dekoratorer introducerades i TypeScript 1.5 och har också föreslagits för ECMAScript-standarden.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • För att använda dekoratorer måste du aktivera alternativet experimentalDecorators i filen tsconfig.json.

Typer av dekoratorer

I TypeScript kan du använda följande fem dekoratorer.

  • Klassdekorerare En dekorerare som tillämpas på en klass.
  • Metoddekorerare En dekorerare som tillämpas på en metod i en klass.
  • Accessor-dekorerare En dekorerare som tillämpas på en getter eller setter av en klassens egenskap.
  • Egendomsdekorerare En dekorerare som tillämpas på en egenskap av en klass.
  • Parametertdekorerare En dekorerare som tillämpas på en parameter i en metod.

Klassdekorator

Klassdekoratorer är dekoratorer som används på klasser. Klassdekoratorer skrivs precis ovanför klassdefinitionen och kan komma åt klasskonstruktorn. De används främst för att ändra klassens beteende eller lägga till metadata.

 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

I det här exemplet används dekoratorn Logger på klassen, och ett meddelande visas i konsolen när klassen initieras.

Metoddekorator

Metoddekoratorer används på klassmetoder och kan ändra metodanrop och beteende. En metoddekorerare tar tre argument.

  1. Prototypen för klassen
  2. Namnet på metoden
  3. Egenskapsbeskrivaren för metoden
 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)

I detta exempel tillämpas dekoratören LogExecutionTime på metoden, och exekveringstiden för metoden loggas.

Åtkomstdekoratör

Åtkomstdekoratörer används på getter eller setter för klasegenskaper. De är användbara för att lägga till beteende vid ändring av egenskapsvärden.

 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

I det här exemplet används en åtkomst-dekoratör för att logga utdata när getter och setter anropas.

Egenskapsdekoratör

Egenskapsdekoratörer används på klasegenskaper men kan inte direkt ändra egenskapens värde eller beteende. De används för att erhålla metadata för egenskaper.

 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'

I detta exempel används dekoratören Readonly på egenskapen title, och egenskapen görs skrivskyddad.

Parametertdekoratör

Parametertdekoratörer används på parametrar i en metod. De används vanligtvis för att lagra metadata eller validera parametrar. Dekoratörer tar tre argument.

  1. Prototypen för klassen
  2. Namnet på metoden
  3. Parameterindex
 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.

I detta exempel används dekoratören LogParameter på den första parametern i metoden greet, och när metoden anropas loggas det att parametern är dekorerad.

Praktiska exempel på dekoratörer

Dekoratörer används ofta i ramverk som Angular, särskilt för beroendeinjektion och metadata-definition. Till exempel används dekoratören @Component för att definiera Angular-komponenter enligt nedan.

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

Således används dekoratörer ofta som kärndelar i ramverk och bibliotek, vilket hjälper till att hålla koden koncis och tydlig.

Sammanfattning av dekoratörer

TypeScript-dekoratörer är kraftfulla verktyg som flexibelt lägger till funktionalitet till klasser, metoder och egenskaper. Att använda anpassade dekoratörer förbättrar kodens underhållbarhet och återanvändbarhet, vilket möjliggör ytterligare abstraktion. Dekoratorer spelar en viktig roll i ramverk som Angular och NestJS, och att förstå dem hjälper till att förstå hur dessa ramverk fungerar på djupet.

Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.

YouTube Video