Logo Jetdev
Logo Jetdev

Typescript: comment faire le « type checking » de nos entités?

Nous sommes parfois amenés à traiter des objets similaires en Typescript et il faut de temps en temps les différencier pour adapter leur traitement.
Imaginons que nous ayons des entités Employee qui héritent une partie de leurs propriétés d’une entité de base Person.
Voyons comment, à l’aide d’exemples simples, nous pouvons différencier leur traitement en faisant du type checking.

(NB: les noms des entités précisent volontairement les types d’entités par soucis de clarté)

 

 

Avec des classes

Nous sommes en effet ici dans un cas typique où la POO peut nous apporter pas mal d’avantages.

Supposons que nous ayons besoin d’une fonction qui nous fournisse une chaîne de caractères représentant les informations des Person/Employee traités. Nous pourrions utiliser le mot clé instanceof pour déterminer de quelle instance de classe est l’objet traité.

Ok, Ok! Je vois d’ici les puristes s’exclamer, et à raison.
Nous sommes ici dans l’illustration.
Tant qu’à faire de la POO, nous devrions plutôt déclarer notre fonction toString() dans la classe!

L’inconvénient des classes dans une utilisation classique dans un frontend est qu’il faudra à chaque réponse d’une requête HTTP ou à chaque création d’un objet, créer les instances de classe avec le constructeur. (new EmployeeClass(firstName, ...))

Avec des types / interfaces

Reprenons l’exemple précédent mais en utilisant des objets et des types. Nous pourrions écrire:

Se pose alors le problème suivant:
Comment discerner les objets selon leur type pour éviter l’erreur ci-dessous?

Nous pourrions commencer par écrire la fonction toString()comme ceci.

Attention, le mot clé in sert à déterminer si la propriété existe dans l’objet, pas la valeur!

Exemple d'utilisation du mot clé in

Le test sur la présence de la propriété est suffisant dans ce cas, mais pas totalement discriminant.

Certains pourraient être tentés d’utiliser l’opérateur typeof pour savoir de quel type est l’objet. Mais cela ne fonctionne qu’avec les types primitifs!

Exemple d'utilisation du mot clé typeof

Nous pouvons, par contre, créer une fonction qui va nous permettre de determiner si l’objet est exactement du type PersonType et une autre pour savoir si l’objet est exactement du type EmployeeType. Vous noterez l’utilisation du type unknown qui signifie que le paramètre aura un type déterminé qu’on ne connait pas pour le moment, à l’inverse de any qui veut plutôt dire que le paramètre sera de n’importe quel type.

Même si ce code est tout à fait valable, Typescript nous donne 3 erreurs:

En effet, nous avons réussi à determiner si toutes les caractéristiques de nos entités passées en paramètres de nos fonctions répondaient à celles attendues par nos types, mais nous n’avons pas indiqué à Typescript que nos entités sont bien de ces types.
Pour cela, nous avons l’opérateur is qui va se positionner sur le type de retour des fonctions précédentes.

L’opérateur is est utile ici uniquement pour une vérification statique (static type checking = avant de transpiler le code, dans l’IDE). En effet, le code Javascript généré n’en tient pas compte:

Par honnêteté intellectuelle, je me dois de vous dire que ces fonctions ne sont pas sûres à 100% non plus. On pourrait augmenter leur niveau de sureté en vérifiant le type de chacun des attributs! 😅
Chaque développeur doit estimer où placer le curseur de la sureté en fonction du besoin!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *