Fermer

octobre 7, 2023

Décorateurs en TypeScript —

Décorateurs en TypeScript —


Dans ce petit conseil, extrait de Libérer la puissance de TypeScriptSteve vous montre comment utiliser les décorateurs dans TypeScript, qui est une nouvelle fonctionnalité de TypeScript 5.

Les décorateurs ont presque fait partie d’ECMAScript depuis aussi longtemps que je me souvienne. Ces outils astucieux nous permettent de modifier les classes et les membres de manière réutilisable. Ils sont présents depuis un certain temps dans TypeScript, bien que sous un drapeau expérimental. Bien que l’itération des décorateurs de l’étape 2 ait toujours été expérimentale, les décorateurs ont été largement utilisés dans des bibliothèques comme MobX, Angulaire, Nidet TypeORM. Les décorateurs de TypeScript 5.0 sont entièrement synchronisés avec le Proposition ECMAScriptqui est à peu près prêt pour les heures de grande écoute, assis à l’étape 3.

Décorateurs Créons une fonction qui modifie le comportement d’une classe et de ses méthodes. Imaginez devoir insérer des instructions de débogage dans nos méthodes. Avant TypeScript 5.0, nous aurions dû copier et coller manuellement les instructions de débogage dans chaque méthode. Avec les décorateurs, on ne fait le travail qu’une seule fois et le changement sera accompagné à travers chaque méthode à laquelle le décorateur est attaché.

Supposons que nous souhaitions créer un décorateur pour signaler qu’une méthode donnée est obsolète :

class Card {
  constructor(public suit: Suit, public rank: Rank) {
    this.suit = suit;
    this.rank = rank;
  }

  get name(): CardName {
    return `${this.rank} of ${this.suit}`;
  }

  @deprecated // 👀 This is a decorator!
  getValue(): number {
    if (this.rank === 'Ace') return 14;
    if (this.rank === 'King') return 13;
    if (this.rank === 'Queen') return 12;
    if (this.rank === 'Jack') return 11;
    return this.rank;
  }

  // The new way to do it!
  get value(): number {
    if (this.rank === 'Ace') return 14;
    if (this.rank === 'King') return 13;
    if (this.rank === 'Queen') return 12;
    if (this.rank === 'Jack') return 11;
    return this.rank;
  }
}

const card = new Card('Spades', 'Queen');
card.getValue();

Nous voulons qu’un message d’avertissement soit enregistré sur la console à chaque fois card.getValue() est appelé. Nous pourrions implémenter le décorateur ci-dessus comme suit :

const deprecated = <This, Arguments extends any[], ReturnValue>(
  target: (this: This, ...args: Arguments) => ReturnValue,
  context: ClassMethodDecoratorContext<
    This,
    (this: This, ...args: Arguments) => ReturnValue
  >,
) => {
  const methodName = String(context.name);

  function replacementMethod(this: This, ...args: Arguments): ReturnValue {
    console.warn(`Warning: '${methodName}' is deprecated.`);
    return target.call(this, ...args);
  }

  return replacementMethod;
};

Cela peut paraître un peu déroutant au début, mais décomposons-le :

  • Notre fonction décorateur prend deux arguments : target et context.
  • target est la méthode elle-même que nous décorons.
  • context sont des métadonnées sur la méthode.
  • Nous renvoyons une méthode qui a la même signature.
  • Dans ce cas, nous appelons console.warn pour enregistrer un avis de dépréciation, puis nous appelons la méthode.

Le ClassMethodDecorator type a les propriétés suivantes :

  • kind: le type du bien décoré. Dans l’exemple ci-dessus, ce sera methodpuisque nous décorons une méthode sur une instance de Card.
  • name: le nom de la propriété. Dans l’exemple ci-dessus, il s’agit getValue.
  • static: une valeur indiquant si l’élément de classe est un élément statique (true) ou une instance (false) élément.
  • private: une valeur indiquant si l’élément de classe a un nom privé.
  • access: un objet qui peut être utilisé pour accéder à la valeur actuelle de l’élément de classe au moment de l’exécution.
  • has: détermine si un objet possède une propriété portant le même nom que l’élément décoré.
  • get: invoque le setter sur l’objet fourni.

Vous pouvez lancer les pneus des exemples de code ci-dessus dans ce terrain de jeu.

Les décorateurs fournissent du sucre syntaxique pratique pour ajouter des messages de journal – comme nous l’avons fait dans l’exemple ci-dessus – ainsi qu’un certain nombre d’autres cas d’utilisation courants. Par exemple, nous pourrions créer un décorateur qui lie automatiquement la méthode à l’instance actuelle ou qui modifie le descripteur de propriété de la méthode ou de la classe.

Cet article est extrait de Libérer la puissance de TypeScriptdisponible sur SitePoint Premium et chez les détaillants de livres électroniques.






Source link