Décorateurs en TypeScript

Décorateurs en TypeScript

Cet article explique les décorateurs dans TypeScript.

YouTube Video

Décorateurs en TypeScript

Les décorateurs TypeScript sont un mécanisme permettant d’ajouter des fonctionnalités ou un comportement supplémentaire aux classes, méthodes, accesseurs, propriétés ou paramètres. Les décorateurs sont un outil puissant pour améliorer la lisibilité et la réutilisabilité du code.

Notions de base sur les décorateurs

Un décorateur est une fonction qui injecte des fonctionnalités supplémentaires dans une classe ou ses membres. Les décorateurs ont été introduits dans TypeScript 1.5 et ont également été proposés pour la norme ECMAScript.

1{
2  "compilerOptions": {
3    "experimentalDecorators": true
4  }
5}
  • Pour utiliser les décorateurs, vous devez activer l’option experimentalDecorators dans le fichier tsconfig.json.

Types de décorateurs

Dans TypeScript, vous pouvez utiliser les cinq décorateurs suivants.

  • Décorateur de classe Un décorateur appliqué à une classe.
  • Décorateur de méthode Un décorateur appliqué à une méthode d'une classe.
  • Décorateur d'accesseur Un décorateur appliqué à un getter ou un setter d'une propriété de classe.
  • Décorateur de propriété Un décorateur appliqué à une propriété d'une classe.
  • Décorateur de paramètre Un décorateur appliqué à un paramètre d'une méthode.

Décorateur de classe

Les décorateurs de classe sont des décorateurs appliqués aux classes. Les décorateurs de classe sont écrits juste au-dessus de la définition de la classe et peuvent accéder au constructeur de la classe. Ils sont principalement utilisés pour modifier le comportement d’une classe ou ajouter des métadonnées.

 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

Dans cet exemple, le décorateur Logger est appliqué à la classe, et un message est affiché dans la console lors de l’initialisation de la classe.

Décorateur de méthode

Les décorateurs de méthode sont appliqués aux méthodes de classe et peuvent modifier les appels et le comportement des méthodes. Un décorateur de méthode prend trois arguments.

  1. Le prototype de la classe
  2. Le nom de la méthode
  3. Le descripteur de propriété de la méthode
 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)

Dans cet exemple, le décorateur LogExecutionTime est appliqué à la méthode, et le temps d'exécution de celle-ci est enregistré.

Décorateur d'Accesseur

Les décorateurs d'accesseur sont appliqués aux getter ou setter des propriétés de classe. Ils sont utiles pour ajouter un comportement lors de la modification des valeurs des propriétés.

 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

Dans cet exemple, un décorateur d'accesseur est utilisé pour enregistrer une sortie lorsque les méthodes getter et setter sont appelées.

Décorateur de Propriété

Les décorateurs de propriété sont appliqués aux propriétés de classe mais ne peuvent pas modifier directement la valeur ou le comportement de la propriété. Ils sont utilisés pour obtenir les métadonnées des propriétés.

 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'

Dans cet exemple, le décorateur Readonly est appliqué à la propriété title, et la propriété est rendue en lecture seule.

Décorateur de Paramètre

Les décorateurs de paramètre sont appliqués aux paramètres d'une méthode. Ils sont généralement utilisés pour stocker des métadonnées ou valider des paramètres. Les décorateurs prennent trois arguments.

  1. Le prototype de la classe
  2. Le nom de la méthode
  3. Index du Paramètre
 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.

Dans cet exemple, le décorateur LogParameter est appliqué au premier paramètre de la méthode greet, et lorsque la méthode est appelée, il enregistre que le paramètre est décoré.

Exemples Pratiques de Décorateurs

Les décorateurs sont largement utilisés dans les frameworks comme Angular, en particulier pour l'injection de dépendances et la définition des métadonnées. Par exemple, utilisez le décorateur @Component pour définir des composants Angular comme ci-dessous.

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

Ainsi, les décorateurs sont souvent utilisés comme des parties essentielles des frameworks et des bibliothèques, aidant à garder le code concis et clair.

Résumé des Décorateurs

Les décorateurs TypeScript sont des outils puissants qui ajoutent de manière flexible des fonctionnalités aux classes, méthodes et propriétés. L'utilisation de décorateurs personnalisés améliore la maintenabilité et la réutilisabilité du code, permettant une abstraction supplémentaire. Les décorateurs jouent un rôle important dans les frameworks comme Angular et NestJS, et les comprendre aide à mieux comprendre le fonctionnement de ces frameworks.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video