Réflexion et introspection en TypeScript : comment le code se regarde lui-même

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Réflexion et introspection en TypeScript : comment le code se regarde lui-même

\n\n

Imaginez un programme capable d'analyser lui-même à l'exécution. Il peut connaître les types de ses variables, les propriétés de ses objets, et même prendre une décision basée sur ces informations. Cela ressemble à de la magie ? En réalité, il s'agit de réflexion et d'introspection — des techniques puissantes de métaprogrammation disponibles en TypeScript.

\n\n

Dans cet article, nous verrons la différence entre réflexion et introspection, comment les utiliser en TypeScript, et pourquoi cela peut être utile dans des projets réels. Pas de théorie ennuyeuse — seulement du code vivant et des exemples pratiques.

\n\n

Qu'est-ce que l'introspection et la réflexion ?

\n\n

Mettons les points sur les i. En programmation, ces termes sont souvent confondus, mais il y a une différence :

\n\n
    \n
  • Introspection — c'est la capacité d'un programme à observer sa propre structure. Vous pouvez connaître les propriétés d'un objet, son type, mais vous ne pouvez pas les modifier.
  • \n
  • Réflexion — c'est un niveau plus avancé : le programme non seulement se regarde, mais modifie aussi son comportement à l'exécution. Par exemple, appeler dynamiquement des méthodes ou créer de nouvelles instances de classes.
  • \n
\n\n

En JavaScript, sur lequel TypeScript est basé, la réflexion est implémentée via Reflect et Proxy. Mais TypeScript ajoute sa propre couche — le typage statique, qui « disparaît » partiellement lors de la compilation. C'est là que les choses deviennent intéressantes.

\n\n

Introspection des types : type guards et typeof

\n\n

La façon la plus simple de regarder à l'intérieur du code est d'utiliser des type guards. Ce sont des constructions qui vérifient le type de données à l'exécution :

\n\n
function isString(value: unknown): value is string {\n  return typeof value === 'string';\n}\n\nfunction processValue(value: unknown) {\n  if (isString(value)) {\n    // TypeScript sait que value est une chaîne\n    console.log(value.toUpperCase());\n  } else {\n    console.log('Ce n\\'est pas une chaîne');\n  }\n}
\n\n

Remarquez value is string — c'est un prédicat de type. Il indique à TypeScript qu'après la vérification, la variable appartient à un type spécifique. C'est de l'introspection pure : nous observons le type, mais ne le modifions pas.

\n\n

Réflexion via l'API Reflect

\n\n

L'objet Reflect est un mécanisme de réflexion intégré en JavaScript. Il permet d'effectuer des actions qui étaient auparavant réalisées par des méthodes « magiques », mais désormais unifiées. Voici quelques exemples :

\n\n
const user = {\n  name: 'Alexis',\n  age: 30,\n};\n\n// Introspection — obtenir la liste des clés\nconsole.log(Reflect.ownKeys(user)); // ['name', 'age']\n\n// Réflexion — lire dynamiquement une propriété\nconst propertyName = 'name';\nconsole.log(Reflect.get(user, propertyName)); // 'Alexis'\n\n// Réflexion — définir dynamiquement une propriété\nReflect.set(user, 'name', 'Marie');\nconsole.log(user.name); // 'Marie'
\n\n

En quoi Reflect est-il meilleur que l'ancien user[prop] ? Premièrement, il retourne un boolean pour les opérations de définition, ce qui est pratique pour les vérifications. Deuxièmement, il fonctionne correctement avec les proxies et les descripteurs de propriétés. Pour TypeScript, c'est particulièrement important car la réflexion permet de contourner le typage statique lorsque c'est vraiment nécessaire.

\n\n

Décorateurs : la réflexion sous stéroïdes

\n\n

Les décorateurs sont sans doute l'exemple le plus frappant de réflexion en TypeScript. Ils permettent d'annoter des classes, méthodes, propriétés et paramètres, puis de modifier leur comportement. Depuis TypeScript 5.0, les décorateurs sont devenus standard (stage 3).

\n\n

Voici à quoi ressemble un décorateur simple pour journaliser l'appel d'une méthode :

\n\n
function logMethod(\n  target: any,\n  propertyKey: string,\n  descriptor: PropertyDescriptor\n) {\n  const originalMethod = descriptor.valu                

Blogs

Book Recommendations