ProgrammationDéveloppeur Fullstack

Comment fonctionne le décorateur de types (Decorator) en TypeScript ? À quoi servent-ils, comment réaliser un décorateur personnalisé, et quels pièges peut-on rencontrer en travaillant avec eux ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les décorateurs sont des annotations spéciales qui permettent de modifier le comportement des classes, propriétés, méthodes ou paramètres en utilisant des méta-informations supplémentaires ou en remplaçant l'implémentation.

Ils sont généralement utilisés pour l'injection de dépendances, la journalisation, la validation, la mise en cache ou la déclaration de métadonnées pour des frameworks comme Angular.

Exemple d'un simple décorateur de méthode :

function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Call: ${propertyKey}(${JSON.stringify(args)})`); return original.apply(this, args); }; } class Example { @Log doSomething(a: number, b: number) { return a + b; } }

Pièges :

  • Les décorateurs ne fonctionnent que si experimentalDecorators est activé dans tsconfig.
  • Incompatibles avec certaines configurations strictes.
  • Les décorateurs ne sont pas toujours appelés dans l'ordre prévu ; il est important de comprendre la pile d'appels.
  • Les décorateurs sur les paramètres ne permettent pas de modifier leurs valeurs directement.

Question piège.

Question : "Peut-on typer les paramètres du décorateur de manière à garantir le type de la méthode à laquelle il est appliqué ?"

Réponse : Dans la plupart des cas, le typage est impossible au moment de l'application du décorateur en raison de la nature dynamique de la méta-programmation. Cependant, via des génériques et des vérifications supplémentaires à l'exécution, on peut ajouter une validation, mais le compilateur TypeScript ne garantira pas au moment de la déclaration de la structure.

Exemple :

function MyDecorator(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<number>) { /* ... */ } // Le compilateur ne garantit pas que la méthode retourne un number

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet.


Histoire

Dans un projet avec de nombreux décorateurs sur des services, on a oublié l'ordre d'application : les décorateurs de propriété ont été appliqués avant tous les paramètres, ce qui a entraîné la perte des métadonnées Inject et l'incapacité de résoudre les dépendances à l'exécution.


Histoire

Les développeurs ont décidé d'appliquer des décorateurs à des fonctions normales plutôt qu'à des méthodes de classe, et ont été surpris par les erreurs de compilation et l'absence d'effet à l'exécution. Dans la spécification TypeScript, les décorateurs ne peuvent être appliqués qu'aux classes et à leurs membres.


Histoire

Après la mise à jour des versions de TypeScript et des paramètres expérimentaux, tout le mécanisme des décorateurs dans un conteneur DI personnalisé s'est effondré : il s'est avéré que la nouvelle version nécessite un support explicite de Reflect-metadata, sinon toutes les méta-informations étaient perdues.