Pourquoi le 'as' en TypeScript est souvent dangereux ?
Tu utilises TypeScript pour la sécurité qu'il apporte à ton code, mais tu as sans doute remarqué que l'opérateur as permet de forcer la compilation même lorsque TypeScript soupçonne des types incompatibles. Cette flexibilité peut être tentante, mais elle cache souvent des pièges. Découvrons ensemble pourquoi l'utilisation excessive du as peut introduire des erreurs d'exécution et comment éviter ces pièges.
Le problème du as: des erreurs masquées à la compilation
En TypeScript, l'opérateur as permet de faire ce qu'on appelle un type assertion, c'est-à-dire de dire à TypeScript "Fais-moi confiance, je sais ce que je fais." Cependant, cet outil peut parfois être une mauvaise idée, car il contourne les vérifications de type. Lorsque tu utilises as, tu prends la responsabilité de garantir que le type est bien correct, même si TypeScript ne peut pas le vérifier. Voyons cela avec quelques exemples concrets.
Exemple 1 : Forcer un type avec as qui n'est pas réellement compatible
Prenons un exemple où tu as un objet de type Person avec certaines propriétés bien définies, mais tu décides d'utiliser as pour le forcer à un type différent, pensant que cela fonctionnera.
typescript
Dans cet exemple, employee n’a pas la propriété role, mais TypeScript ne renvoie pas d'erreur lors de la compilation grâce au as. Cependant, à l'exécution, employee.role est undefined, ce qui peut provoquer des erreurs si ton code s'attend à une valeur de type string.
Exemple 2 : Passer outre les vérifications avec as unknown as
Parfois, on voit des développeurs utiliser des castings en chaîne pour forcer un type via unknown, comme dans cet exemple :
typescript
Ici, on prend une valeur data qui pourrait être n'importe quoi, et on la caste en number via unknown. À la compilation, tout semble fonctionner, mais lors de l'exécution, l'addition produit NaN parce que data était en réalité une chaîne de caractères.
Exemple 3 : Manipuler des objets partiels
Prenons un autre cas classique où l’on force un objet partiellement complété à un type complet en pensant que tout ira bien :
typescript
L'objet partialProduct est converti en Product alors qu'il lui manque la propriété price. Cette absence n’est pas détectée par TypeScript grâce au as, mais conduit à un undefined qui peut générer des erreurs d'exécution si cette valeur est utilisée sans vérification préalable.
Comment éviter les erreurs avec Zod
Pour éviter les problèmes générés par as, une bonne pratique est de valider les données à l'exécution, en particulier si elles proviennent d'une source externe. C'est ici que Zod entre en scène. Zod est une bibliothèque de validation de schémas en TypeScript qui permet de définir des types sécurisés et de les valider en runtime.
Avec Zod, au lieu de forcer un type avec as, tu peux valider et convertir les données avec un schéma prédéfini. Par exemple :
typescript
Dans cet exemple, Zod vérifie que partialProduct respecte bien le schéma Product. Si des propriétés manquent, Zod renvoie une erreur de validation au lieu de laisser passer des valeurs undefined. Grâce à Zod, tu sécurises tes données et évites les erreurs d'exécution liées aux types incomplets ou incorrects.
Conclusion
L'opérateur as peut être une solution rapide pour passer outre les vérifications de TypeScript, mais il introduit des risques d'erreurs d'exécution, surtout quand on force des types sans validation. En utilisant une bibliothèque comme Zod, tu peux valider tes données en runtime et ainsi tirer pleinement parti de la sécurité de TypeScript, même dans les cas où as semblait la seule solution.