Dekoratører i TypeScript

Dekoratører i TypeScript

Denne artikkelen forklarer dekoratører i TypeScript.

YouTube Video

Dekoratører i TypeScript

TypeScript-dekoratører er en mekanisme for å legge til ekstra funksjonalitet eller oppførsel til klasser, metoder, tilganger, egenskaper eller parametere. Dekoratører er et kraftig verktøy for å forbedre lesbarhet og gjenbrukbarhet av kode.

Grunnleggende om dekoratører

En dekoratør er en funksjon som injiserer ekstra funksjonalitet i en klasse eller dens medlemmer. Dekoratører ble introdusert i TypeScript 1.5 og har også blitt foreslått for ECMAScript-standarden.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • For å bruke dekoratører må du aktivere alternativet experimentalDecorators i tsconfig.json-filen.

Typer dekoratører

I TypeScript kan du bruke følgende fem dekoratører.

  • Klasse-dekoratør En dekoratør brukt på en klasse.
  • Metode-dekoratør En dekoratør brukt på en metode i en klasse.
  • Tilgangsdekoratør En dekoratør brukt på en getter eller setter for en klasseegenskap.
  • Egenskapsdekoratør En dekoratør brukt på en egenskap i en klasse.
  • Parameterdekoratør En dekoratør brukt på en parameter i en metode.

Klasse-dekoratør

Klasse-dekoratører er dekoratører som brukes på klasser. Klasse-dekoratører skrives rett over klassedefinisjonen og kan få tilgang til klassens konstruktør. De brukes hovedsakelig til å endre klassens oppførsel eller legge til 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 eksemplet brukes Logger-dekoratøren på klassen, og en melding vises i konsollen når klassen initialiseres.

Metode-dekoratør

Metode-dekoratører brukes på klassens metoder og kan endre metodeanrop og oppførsel. En metode-dekoratør tar tre argumenter.

  1. Prototype av klassen
  2. Navnet på metoden
  3. Egenskapens deskriptor for 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 dette eksempelet brukes dekoratøren LogExecutionTime på metoden, og kjøretiden for metoden blir logget.

Tilgangsdekoratør

Tilgangsdekoratører brukes på getter eller setter for klasseegenskaper. De er nyttige for å legge til oppførsel når egenskapsverdier endres.

 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 eksempelet brukes en aksessordekorator for å logge utdata når getter og setter kalles.

Egenskapsdekoratør

Egenskapsdekoratører brukes på klasseegenskaper, men kan ikke direkte endre egenskapens verdi eller oppførsel. De brukes for å hente metadata om 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 dette eksempelet brukes dekoratøren Readonly på egenskapen title, og egenskapen gjøres skrivebeskyttet.

Parameterdekoratør

Parameterdekoratører brukes på en metodes parametere. De brukes vanligvis til å lagre metadata eller validere parametere. Dekoratører tar tre argumenter.

  1. Prototype av 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 eksempelet brukes dekoratøren LogParameter på det første parameteret til metoden greet, og når metoden kalles, logger den at parameteret er dekorert.

Praktiske eksempler på dekoratører

Dekoratører brukes mye i rammeverk som Angular, spesielt for avhengighetsinjeksjon og definisjon av metadata. For eksempel kan @Component-dekoratøren brukes for å definere Angular-komponenter som nedenfor.

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

Dermed brukes dekoratører ofte som kjerneelementer i rammeverk og biblioteker, noe som bidrar til å holde koden konsis og klar.

Oppsummering av dekoratører

TypeScript-dekoratører er kraftige verktøy som fleksibelt legger til funksjonalitet i klasser, metoder og egenskaper. Bruk av egendefinerte dekoratører forbedrer kodevedlikehold og gjenbruk, og muliggjør ytterligere abstraksjon. Dekoratører spiller en viktig rolle i rammeverk som Angular og NestJS, og det å forstå dem hjelper med en dypere forståelse av hvordan disse rammeverkene fungerer.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video