Dekoratorer i TypeScript

Dekoratorer i TypeScript

Denne artikel forklarer dekoratorer i TypeScript.

YouTube Video

Dekoratorer i TypeScript

TypeScript-dekoratorer er en mekanisme til at tilføje ekstra funktionalitet eller adfærd til klasser, metoder, adgange, egenskaber eller parametre. Dekoratorer er et kraftfuldt værktøj til at forbedre kode-læselighed og genanvendelighed.

Grundlæggende om dekoratorer

En dekorator er en funktion, der tilføjer ekstra funktionalitet til en klasse eller klassemedlemmer. Dekoratorer blev introduceret i TypeScript 1.5 og er også blevet foreslået til ECMAScript-standarden.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • For at bruge dekoratorer skal du aktivere experimentalDecorators-indstillingen i tsconfig.json-filen.

Typer af dekoratorer

I TypeScript kan du bruge følgende fem dekoratorer.

  • Klasse-dekoratør En dekoratør anvendt på en klasse.
  • Metode-dekoratør En dekoratør anvendt på en metode i en klasse.
  • Accessor-dekoratør En dekoratør anvendt på en getter eller setter for en klasseegenskab.
  • Egenskabs-dekoratør En dekoratør anvendt på en egenskab i en klasse.
  • Parameter-dekoratør En dekoratør anvendt på en parameter i en metode.

Klasse Dekorator

Klasse-dekoratorer er dekoratorer, der anvendes på klasser. Klasse-dekoratorer skrives lige over klassedefinitionen og kan få adgang til klassens konstruktor. De bruges primært til at ændre klassens adfærd eller tilføje 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 dette eksempel anvendes Logger-dekoratoren på klassen, og der vises en besked i konsollen, når klassen initialiseres.

Metode Dekorator

Metode-dekoratorer anvendes på klassemetoder og kan ændre metodekald og adfærd. En metode-dekoratør tager tre argumenter.

  1. Prototype for klassen
  2. Navnet på metoden
  3. Metodens egenskabsbeskrivelse
 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 dette eksempel anvendes LogExecutionTime-dekorationen på metoden, og metodens eksekveringstid logges.

Accessor-dekoration

Accessor-dekorationer anvendes på getter eller setter af klasseegenskaber. De er nyttige til at tilføje adfærd, når egenskabsværdier ændres.

 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 dette eksempel bruges en accessor-dekorer til at logge output, når getter og setter bliver kaldt.

Egenskabs-dekoration

Egenskabs-dekorationer anvendes på klasseegenskaber, men kan ikke direkte ændre egenskabens værdi eller adfærd. De bruges til at få metadata for egenskaber.

 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 dette eksempel anvendes Readonly-dekorationen på title-egenskaben, og egenskaben gøres skrivebeskyttet.

Parameter-dekoration

Parameter-dekorationer anvendes på parametre af en metode. De bruges normalt til at gemme metadata eller validere parametre. Dekorationer tager tre argumenter.

  1. Prototype for klassen
  2. Navnet på metoden
  3. Parameterindeks
 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 dette eksempel anvendes LogParameter-dekorationen på den første parameter af greet-metoden, og når metoden kaldes, logges det, at parameteren er dekoreret.

Praktiske eksempler på dekorationer

Dekorationer bruges bredt i rammer som Angular, især til afhængighedsinjektion og metadata-definition. For eksempel bruges @Component-dekorationen til at definere Angular-komponenter som nedenfor.

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

Dekorationer bruges således ofte som kerneelementer i rammer og biblioteker, hvilket hjælper med at holde koden kortfattet og klar.

Opsummering af dekorationer

TypeScript-dekorationer er kraftfulde værktøjer, der fleksibelt tilføjer funktionalitet til klasser, metoder og egenskaber. Brug af brugertilpassede dekorationer forbedrer kodens vedligeholdelse og genbrug, hvilket muliggør yderligere abstraktion. Dekoratorer spiller en vigtig rolle i frameworks som Angular og NestJS, og at forstå dem hjælper med en dybere forståelse af, hvordan disse frameworks fungerer.

Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.

YouTube Video