Cum se creează decoratori TypeScript personalizat

Decoratorii sunt o caracteristică din TypeScript care permite modificarea claselor, metodelor, proprietăților sau parametrilor în timpul execuției. Sunt funcții speciale care oferă capabilități de metaprogramare. În TypeScript, decoratorii sunt adesea folosiți în cadre precum Angular pentru a îmbunătăți funcționalitatea. Acest articol explică pas cu pas cum să creați decoratori personalizați.

Tipuri de decoratori în TypeScript

Există patru tipuri principale de decoratori în TypeScript:

  • Decoratori de clasă
  • Decoratori metoda
  • Decoratori accesorii
  • Decoratori imobiliari

Activarea decoratorilor în TypeScript

Pentru a utiliza decoratori într-un proiect TypeScript, opțiunea experimentalDecorators trebuie să fie activată în fișierul tsconfig.json.

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Crearea unui decorator de clasă

Decoratorii de clasă sunt aplicați constructorului unei clase. Sunt utile pentru adăugarea de metadate sau funcționalități la clasă. Iată un exemplu despre cum să creați un decorator de clasă simplu.

function logClass(constructor: Function) {
  console.log(`Class ${constructor.name} is created`);
}

@logClass
class Person {
  constructor(public name: string) {}
}

const person = new Person("John");
// Output: Class Person is created

Crearea unui Decorator de Metode

Decoratorii de metode sunt aplicați metodelor de clasă. Ele pot fi folosite pentru a modifica sau observa comportamentul metodei. Mai jos este un exemplu de decorator de metodă care înregistrează execuția metodei.

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyKey} is called with arguments:`, args);
    return originalMethod.apply(this, args);
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a: number, b: number) {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3); 
// Output: Method add is called with arguments: [2, 3]

Crearea unui decorator de proprietate

Decoratorii de proprietate pot fi folosiți pentru a observa sau modifica proprietăți. Iată un exemplu în care un decorator de proprietate se asigură că o proprietate are o valoare implicită.

function defaultValue(value: any) {
  return function (target: any, propertyKey: string) {
    let propertyValue = value;

    const getter = function () {
      return propertyValue;
    };

    const setter = function (newValue: any) {
      propertyValue = newValue || value;
    };

    Object.defineProperty(target, propertyKey, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true,
    });
  };
}

class User {
  @defaultValue('Anonymous')
  name!: string;
}

const user = new User();
console.log(user.name); // Output: Anonymous
user.name = 'Alice';
console.log(user.name); // Output: Alice

Crearea unui Decorator de parametri

Decoratorii de parametri sunt aplicați parametrilor unei metode. Ele pot fi utile pentru sarcini precum validarea sau înregistrarea argumentelor. Iată un exemplu de decorator de parametri.

function logParameter(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} is being decorated`);
}

class Vehicle {
  drive(@logParameter speed: number) {
    console.log(`Driving at speed ${speed}`);
  }
}

const vehicle = new Vehicle();
vehicle.drive(50);
// Output: Parameter at index 0 in method drive is being decorated

Concluzie

Decoratorii din TypeScript oferă capabilități puternice de meta-programare care pot îmbunătăți și extinde funcționalitatea claselor, metodelor și proprietăților. Folosind decoratori personalizați, este posibil să se creeze structuri de cod reutilizabile, eficiente și organizate. Acest ghid a demonstrat crearea diferitelor tipuri de decoratori: clasă, metodă, proprietate și parametru.