Comment créer des décorateurs TypeScript personnalisés

Les décorateurs sont une fonctionnalité de TypeScript qui permet de modifier des classes, des méthodes, des propriétés ou des paramètres lors de l'exécution. Ce sont des fonctions spéciales qui offrent des capacités de métaprogrammation. Dans TypeScript, les décorateurs sont souvent utilisés dans des frameworks comme Angular pour améliorer les fonctionnalités. Cet article explique comment créer des décorateurs personnalisés étape par étape.

Types de décorateurs dans TypeScript

Il existe quatre principaux types de décorateurs dans TypeScript:

  • Décorateurs de classe
  • Décorateurs de méthode
  • Décorateurs d'accessoires
  • Décorateurs de propriétés

Activation des décorateurs dans TypeScript

Pour utiliser des décorateurs dans un projet TypeScript, l'option experimentalDecorators doit être activée dans le fichier tsconfig.json.

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

Créer un décorateur de classe

Les décorateurs de classe sont appliqués au constructeur d'une classe. Ils sont utiles pour ajouter des métadonnées ou des fonctionnalités à la classe. Voici un exemple de création d'un décorateur de classe simple.

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

Création d'un décorateur de méthode

Les décorateurs de méthode sont appliqués aux méthodes de classe. Ils peuvent être utilisés pour modifier ou observer le comportement de la méthode. Vous trouverez ci-dessous un exemple de décorateur de méthode qui enregistre l'exécution de la méthode.

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]

Créer un décorateur de propriété

Les décorateurs de propriétés peuvent être utilisés pour observer ou modifier des propriétés. Voici un exemple où un décorateur de propriétés garantit qu'une propriété possède une valeur par défaut.

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

Création d'un décorateur de paramètres

Les décorateurs de paramètres sont appliqués aux paramètres d'une méthode. Ils peuvent être utiles pour des tâches telles que la validation ou la journalisation des arguments. Voici un exemple de décorateur de paramètres.

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

Conclusion

Les décorateurs de TypeScript offrent de puissantes capacités de métaprogrammation qui peuvent améliorer et étendre les fonctionnalités des classes, des méthodes et des propriétés. En utilisant des décorateurs personnalisés, il est possible de créer des structures de code réutilisables, efficaces et organisées. Ce guide a démontré la création de différents types de décorateurs: classe, méthode, propriété et paramètre.