09/02/2021 Tech
Pourquoi TypeScript ?
J’aimerais commencer cet article en expliquant pourquoi j’ai choisi le titre "Pourquoi TypeScript” plutôt que “TypeScript, c’est mieux”. Mon article n'est pas seulement pour les développeurs, il est aussi à destination de toutes les personnes qui travaillent sur un projet numérique, du chef de projet au client qui paye pour avoir son site internet.
Chacune de ces personnes va avoir sa propre expérience vis-à-vis d’un nouveau langage et ses propres objectifs (mais bien sûr souvent partagés). Certains vont se concentrer sur l’amélioration de l’expérience développeur, d’autres sur la livraison d’un site avec le moins de bugs critiques en production. D’autres vont prendre en considération des problématiques de recrutement de développeurs à l’aise avec TypeScript. Et il faut évidemment prendre en compte la subjectivité des développeurs face à tel ou tel langage, car nous n’aimons pas tous les mêmes choses.
Je ne peux donc pas dire : “TypeScript, c’est mieux”, parce que ce n’est peut-être pas ce qui est le plus adapté pour vous et/ou votre projet. Je vais donc vous expliquer pourquoi TypeScript est mieux pour moi !
Pourquoi de plus en plus de développeurs sont conquis par ce langage? Pourquoi de plus en plus de librairies vont-elles à minima exposer des types pour leurs objets, voire complètement migrer vers TypeScript? L’objectif est de vous permettre de faire un choix plus éclairé pour votre projet.
1. Qu’est-ce que TypeScript ?
TypeScript est un langage de programmation typé créé par Microsoft en octobre 2012 avec la sortie de la version 0.8. Le langage a connu son essor lors de la sortie de la version 2.0 en septembre 2016.
TypeScript est un super-set de JavaScript, cela veut dire que tout ce que JavaScript fait, TypeScript sait le faire et ajoute en plus la notion de Type.
Le typage, c’est quoi ? C’est contraindre le programme à respecter une définition de données pour une variable sous peine de provoquer des erreurs à la compilation ou à l’exécution. Arrêtons-nous quelques instants ici pour bien expliciter ce que signifient compilation (transpilation dans un contexte front-end) et exécution.
Lorsque nous développons une interface, nous créons des fichiers avec du code et une certaine architecture organise ces fichiers. Nous pouvons développer en Typescript, parfois en JavaScript, ou les deux à la fois. Les librairies et/ou framework que nous utilisons vont aussi parfois imposer un langage ou une structure. L’ensemble de ces fichiers et leur architecture ne sont pas directement compréhensibles par les navigateurs. Ces derniers savent interpréter du JavaScript, mais ils sont incapables de faire de même avec TypeScript.
Nous devons donc traduire les fichiers sur lesquels nous travaillons pour obtenir un livrable compréhensible pour le navigateur : un (ou plusieurs) fichier(s) JavaScript(s).
Cette traduction est l’étape de transpilation (traduire et compiler).
L’exécution se produit lorsque vous utilisez un site : votre navigateur télécharge et interprète le JavaScript. Cette phase d’exécution est aussi appelée runtime. Une erreur présente dans le runtime entraîne un crash de votre application JavaScript.
Ce qui est très important à comprendre est que le livrable étant nécessairement en JavaScript, TypeScript intervient avant et pendant l’étape de transpilation : c’est une aide au développement. TypeScript va permettre de détecter d’éventuelles erreurs dès la transpilation, avant même que le code n’arrive sur le navigateur, permettant ainsi d’éviter des crashs applicatifs.
Depuis la sortie de la version 4.0 en novembre dernier, la communauté de développeur Typescript a grandi :
- TypeScript est le langage utilisé par le framework Angular
- La plupart des librairies JavaScript exportent des types même si leur code est en JavaScript. Si elles ne le font pas, la communauté le fera et exposera ses types pour elles via DefinitelyTyped
- Certaines librairies vont même jusqu’à écrire des documentations expliquant comment utiliser TypeScript avec leurs outils (exemple avec redux-toolkit)
2. La détection des erreurs
TypeScript permet donc de détecter des erreurs dès la transpilation. Pour illustrer la différence avec le JavaScript et la puissance de cette détection, voici deux vidéos de l’implémentation du même code en JavaScript et en TypeScript :
La version en JavaScript
L’objectif est d’appeler la fonction triggerError au clique sur le bouton. La fonction triggerError veut accéder au champ cat d’un objet qui doit lui être passé en paramètre.
J’ai volontairement omis de lui passer ce paramètre pour provoquer une erreur. Vous pouvez constater que cette erreur n’est pas détectée lors de l’écriture du code, ni lors de la transpilation. Elle est détectée au runtime, une fois que le code a fini sur le navigateur et une fois que l’utilisateur a cliqué sur le bouton, provoquant l’exécution du code problématique. En somme, l’erreur est arrivée pendant la phase de tests réels ou (pire!) en production.
La version en TypeScript
Vous l’avez compris: l’erreur a été détectée directement lors de l’écriture du code (grâce aux IDE que nous utilisons qui supportent TypeScript tel que VSCode ou Webstorm) et dès la transpilation. Il est impossible que ce code incorrect arrive sur le navigateur, car il est impossible de passer l’étape qui permet de fournir le livrable pour le navigateur. Le développeur réalise son erreur au moment même où il est en train d’écrire son code, le diagnostic est immédiat et facile. Il est accompagné.
Attention! Il est important de préciser qu’utiliser TypeScript dans votre projet n’empêchera pas toute erreur au runtime (en production) : le “sans faute” est impossible. TypeScript est un outil, une aide au développement. Comme tout outil, il peut être plus ou moins bien utilisé et il ne peut pas pallier toutes les situations.
Cependant, TypeScript peut aider à réduire fortement les erreurs en production. Cela signifie plus de confiance dans le développement de nouvelles fonctionnalités, ou dans la mise en place d’évolution de l’existant, autant pour les développeurs que pour les chefs de projet que pour tous les intervenants sur le projet.
L’écriture des types demande beaucoup de rigueur car ils vont cadrer le code et être utilisés sur le long terme (c’est bien ce qui permet de maintenir plus facilement le site). Un faux type pourrait mener à de nombreux problèmes, car il sera utilisé par toute l’équipe.
3. Une expérience développeur améliorée
Parlons un peu de l’expérience développeur que j’ai mentionnée en introduction. Au début, lors de la prise en main du langage, nous avons constaté parfois un peu de réticence chez les développeurs. C’est un nouveau langage, il faut apprendre et monter en compétence et cela prend un peu de temps. Si on reprend la définition du typage : “contraindre le programme à respecter une définition de données” alors nous parlons bien de contraintes supplémentaires. Il faut se plier aux exigences des types. Il faut rédiger ces derniers et c’est du temps en moins pour développer directement de nouvelles fonctionnalités. Cela peut être stressant à l’approche de livraisons.
Pour autant, après quelques mois, ces mêmes développeurs qui ont eu quelques difficultés au début vont souvent dire : “je ne pourrais plus me passer de TypeScript”. La force de TypeScript ne se fait pas sentir dans les premiers moments de vie d’un projet, mais bien sur le long terme.
NB : Le langage typescript évolue très vite et la communauté de développeurs est de plus en plus grande. Les nouvelles versions sont régulières et facilitent la prise en main de typescript et son utilisation au quotidien, en plus d’ajouter des fonctionnalités toujours plus puissantes.
Une fois à l’aise avec le langage, on constate que les développeurs ont une meilleure compréhension du code et des librairies utilisées.
Mais l’aspect le plus important et le plus révolutionnaire qui est apporté par TypeScript pour les développeurs front-end, c’est l’auto-complétion. Les développeurs back-end doivent rigoler doucement, car c’est quelque chose qu’ils connaissent depuis belle lurette ! Mais pour les développeurs front, c’est LE truc qui rend accroc à TypeScript.
TypeScript fait office de documentation vivante, et permet donc aux outils (IDE) de proposer une auto-complétion pertinente et fiable.
Voici deux vidéos pour illustrer mon propos (en commençant par TypeScript cette fois-ci) :
La version en TypeScript : (documentationTs)
L’objectif est simplement d’afficher à l’écran certaines informations qui sont passées à notre composant React via les props : le nom, le prénom et la couleur d’un certain chat.
Comme vous pouvez le constater, la structure des props est décrite via un type. Le développeur sait exactement comment il doit accéder aux différentes propriétés de l’objet.
De plus, l’auto-complétion lui permet d’accéder directement aux propriétés et d’éviter notamment des fautes de frappe.
La version en JavaScript va permettre de réellement prendre la mesure de l’apport de TypeScript ici.
La version en JavaScript : (documentationJs)
Lorsque le développeur regarde le code du composant React, il ne sait pas grand-chose. Il sait qu’il y a un objet props, mais il ne connaît pas sa structure. Avant de faire quoi que ce soit, il doit donc ajouter un log, transpiler son code, déployer sa version sur le navigateur et aller jusqu’à l’exécution du code pour déterminer de quoi est composé l’objet.
NB : L’’exemple ici est simple : le log arrive dès l’exécution du fichier JavaScript sur le navigateur. Parfois, comme avec le bouton dans l’exemple précédent, le code en question n’est exécuté que suite à une action utilisateur. Si la donnée que vous recherchez est dans un bout de code qui est exécuté lors de la validation de la page 6 d’un formulaire fastidieux…bonne chance.
Une fois que le développeur connaît la structure de l’objet, il peut commencer à coder. Mais là encore, sans l’auto-complétion et la détection des erreurs, il n’est pas à l’abri de faire une faute de frappe, et de devoir refaire des allers-retours.
4. TypeScript apporte un cadre
Ce dernier point est moins factuel, car il s’agit plus d’un retour d’expérience après 3 ans d’utilisation de TypeScript.
Les types peuvent parfois être contraignants, mais ils apportent un cadre à notre code. Les développeurs doivent nécessairement être plus rigoureux.
Il est bien évidemment possible d’être rigoureux sans TypeScript. Mais avec il est difficile de ne plus l’être (à condition de bien utiliser TypeScript, évidemment).
Son utilisation m’a permis de réfléchir différemment et d’acquérir un certain nombre de réflexes :
- Réfléchir plus en amont avant d’écrire et mieux architecturer son code.
- Maîtriser et connaître pleinement la structure des données dans mon application. TypeScript me permet de créer mon propre modèle de données, celui-ci est potentiellement complètement décorrélé des services externes que je consomme. Mon code est plus agnostique.
- Penser réutilisable.
- Penser au prochain développeur qui va utiliser mon code : est-ce que mon type est assez explicite ? Est ce qu’il est correct ? Est ce qu’il est logique que ma fonction renvoie 5 types différents en fonction des chemins de code ? Est ce qu’il ne serait pas plus simple, plus lisible, et moins sujet aux erreurs de retourner toujours le même type ? Et donc de simplifier ma fonction et/ou de changer l’architecture.
J’aurais très bien pu faire tout cela sans TypeScript. mais utiliser ce langage m’a “ouvert les chakras” et a provoqué et/ou accéléré ce processus.
J’espère que cet article vous a permis de mieux comprendre l’engouement des développeurs autour de ce langage et les différents concepts qu’il introduit.
Je n’irais pas jusqu’à dire que TypeScript a “changé ma vie”. Cependant, cela a sacrément amélioré mon expérience de développeur et la qualité du code que je produis, et donc des applications délivrées (comme pour de nombreux développeurs).
NB : Mais quand même, TypeScript, c’est mieux ?