ProgrammationDéveloppeur Frontend

Décrivez le mécanisme des gardiens de type (Type Guards) en TypeScript et donnez des exemples de leur utilisation. Quel est le principal avantage et quels points particuliers faut-il prendre en compte lors de la mise en œuvre de fonctions de garde de type personnalisées ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les gardiens de type sont des mécanismes qui permettent de préciser le type d'une variable dans un bloc de code, basé sur certaines vérifications (par exemple, en utilisant typeof, instanceof, ou des fonctions spéciales retournant des expressions de type param is SomeType).

Le principal avantage est la sécurité et l'élimination des erreurs d'exécution grâce à la vérification des types au moment de la compilation.

Exemple :

interface Fish { swim: () => void } interface Bird { fly: () => void } function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; } function move(pet: Fish | Bird) { if (isFish(pet)) { pet.swim(); } else { pet.fly(); } }

Ici, la fonction isFish est un garde de type personnalisé.

Points particuliers :

  • Toute vérification logique supplémentaire doit être strictement liée à la typisation.
  • Les erreurs dans les fonctions de garde de type peuvent entraîner une définition incorrecte des types lors de l'exécution.

Question piège.

Question : "Le compilateur TypeScript se fondera-t-il toujours uniquement sur la valeur de retour de la fonction guard, ou utilise-t-il également une analyse à l'intérieur de la fonction ?"

Réponse : Le compilateur TypeScript s'appuie uniquement sur la signature de la valeur de retour param is Type. Ce qui se passe à l'intérieur de la fonction guard n'est pas analysé quant à la validité de l'implémentation.

Exemple (erreur dangereuse !) :

function isString(x: any): x is string { return true; } // Le compilateur considérera que c'est toujours une chaîne, même si ce n'est pas le cas : if (isString(123)) { // ici x est de type string, mais c'est en réalité un nombre }

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

Dans un projet avec des DTO partagés entre le front-end et le back-end, on a oublié d'ajouter une vérification stricte à l'intérieur d'un garde de type personnalisé. En conséquence, certaines données étaient faussement perçues comme le type requis, entraînant des pannes côté client lorsqu'on essayait d'utiliser une propriété manquante.


Histoire

Un développeur a écrit un garde de type en se basant sur un champ optionnel, cependant la structure des données ne permettait pas d'avoir ce champ. Au final, le switch-case typé manquait d'une branche, et le compilateur ne lançait pas d'avertissement - des exceptions se produisaient à l'exécution.


Histoire

Dans l'un des services, lors du passage à TypeScript, on comptait uniquement sur les gardiens de type intégrés (typeof, instanceof). Lors du changement de prototype des objets, les vérifications devenaient incorrectes, ce qui a provoqué des bugs difficiles à déboguer en production.