ProgrammationDéveloppeur TypeScript

Expliquez le rôle et la mécanique de l'opérateur typeof en TypeScript pour la typage des variables. Comment l'utiliser pour inférer le type d'une variable ou de la structure d'un objet, et dans quels cas est-il préférable à la définition manuelle du type ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

TypeScript prend en charge l'opérateur typeof non seulement à l'exécution (comme en JavaScript), mais aussi au moment de la compilation pour inférer le type d'une expression. Cela permet d'obtenir le type d'une variable, d'une fonction ou d'une structure d'objet déjà déclarée, rendant la typage flexible et réduisant le risque de duplication et de désynchronisation des types.

Historique de la question

À l'origine, en JavaScript, l'opérateur typeof était utilisé pour déterminer le type d'une valeur à l'exécution. TypeScript a étendu ce mécanisme — maintenant, typeof au moment de la compilation crée une référence au type de la valeur d'une variable ou au résultat d'une fonction. Cela est particulièrement utile lors du travail avec des structures complexes, des configurations, ainsi que lors de la réutilisation de types entre modules.

Problème

Lors de la déclaration manuelle de types, il est facile de faire une erreur : modifier la définition d'une structure et oublier de mettre à jour la déclaration de type ou d'interface, ou copier incorrectement des types entre des objets. Cela conduit à une désynchronisation du code et à des erreurs d'exécution. Lors de l'utilisation de typeof, le type est inféré dynamiquement et correspond toujours à la structure de données actuelle.

Solution

Pour déclarer une variable avec un type correspondant à une structure ou constante existante, on utilise l'opérateur typeof :

const config = { host: "localhost", port: 8080, }; let serverCfg: typeof config; // Le type de serverCfg est le même que celui de config

Pour typifier une fonction, retournant une structure définie :

function makeUser() { return { id: 1, name: "Alex" }; } type User = ReturnType<typeof makeUser>; // User : {id: number; name: string;}

Caractéristiques clés :

  • typeof en TS retourne le type de la valeur d'une variable ou du résultat d'une expression au moment de la compilation.
  • Permet d'éviter la duplication et la désynchronisation des types.
  • Souvent combiné avec d'autres types utilitaires (ReturnType, Parameters), ainsi qu'avec keyof pour obtenir une liste des clés d'un objet.

Questions pièges.

L'opérateur typeof est-il exécuté en TypeScript à l'exécution ?

Non, le typeof typé fonctionne uniquement lors de la compilation, ne figurant pas dans le code d'exécution, bien que l'opérateur JavaScript typeof existe aussi à l'exécution.

Peut-on utiliser typeof pour inférer le type des propriétés d'une classe ?

Oui, mais uniquement si la propriété a déjà été déclarée comme statique ou avec une valeur initiale, sinon il y aura une erreur. Pour les propriétés privées/protégées publiques — seules les propriétés/méthodes publiques sont prises en compte.

Y a-t-il une différence entre 'let x: typeof y;' et 'let x = y;'?

Du point de vue typologique — dans les deux cas, le compilateur inférera le type automatiquement. Toutefois, 'typeof' peut être utilisé pour écrire des déclarations de types sans initialisation ou pour des combinaisons plus complexes avec des types utilitaires.

Erreurs typiques et anti-patterns

  • Utiliser typeof pour la vérification de type javascript habituelle typeof x === 'string' — cela fonctionnera à l'exécution, pas comme un type compilé.
  • Réutiliser une valeur de structure lorsque seule sa forme est nécessaire (mieux vaut extraire la structure dans un type séparé).

Exemple de la vie réelle

Cas négatif

Dans le projet, un grand objet de configuration de l'application est décrit séparément comme type, séparément comme variable. Lors de la modification de la structure, on oublie de mettre à jour le type, ce qui entraîne des erreurs de fonctionnement de l'API.

Avantages : Travail flexible avec les types, possibilité de redéfinir les types via type ou interface.

Inconvénients : Grand risque de désynchronisation entre la structure et les types, mauvaise maintenabilité.

Cas positif

Utiliser typeof pour obtenir le type actuel de la structure d'un objet lors de la déclaration de nouvelles variables et lors de la génération du type pour l'interface API.

Avantages : Le type correspond toujours à la valeur, faible probabilité d'erreur, bonne complétion automatique.

Inconvénients : Si l'objet est très complexe, le type final peut devenir déroutant à lire pour les débutants.