TypeScript avant de passer à l’échelle

    On traite les types comme une taxe que paient les grandes équipes. Le mécanisme qui les rend utiles est le plus fort dans les petites équipes qui changent souvent d’avis.

    On plaide généralement pour TypeScript au nom des autres. Les grandes équipes en ont besoin. Les bases de code à nombreux contributeurs en ont besoin. Sous-entendu : un projet à deux personnes peut s’en passer et l’ajouter plus tard, quand le désordre justifiera la cérémonie.

    Cette façon de présenter les choses inverse le mécanisme. Les types ne sont pas d’abord un outil de coordination pour grands groupes. Ils servent à écrire noir sur blanc des décisions pour que les changer coûte peu — et les petites équipes changent d’avis en permanence.

    Ce qu’ils font réellement pour vous

    Un type est une affirmation sur la forme de vos données, vérifiée partout où ces données sont utilisées. L’intérêt n’est pas que le compilateur attrape les fautes de frappe. C’est que, lorsqu’une affirmation change, vous recevez la liste de tous les endroits qui supposaient l’ancienne.

    Imaginons qu’un utilisateur ait un avatar facultatif. Vous décidez qu’il devient obligatoire, avec une valeur par défaut générée. Sans types, vous cherchez le mot, trouvez la plupart des usages, et découvrez les autres en production. Avec, vous changez la déclaration et le compilateur vous remet la liste complète — y compris le composant dont vous aviez oublié l’existence et celui écrit par quelqu’un qui est parti depuis.

    Le bénéfice n’est pas d’attraper des erreurs. C’est de connaître toute l’étendue d’un changement avant de le faire.

    Voilà pourquoi les petites équipes en profitent tôt. Une petite équipe n’a pas les moyens d’avoir du code qui lui fait peur. Chaque fichier est un fichier que quelqu’un devra modifier le mois prochain, en général quelqu’un d’autre que son auteur, souvent une version de vous-même qui a oublié le raisonnement.

    Pourquoi « plus tard » coûte plus cher qu’il n’y paraît

    Ajouter des types à une base de code existante n’est pas le même travail que les écrire au fil de l’eau. Arriver après coup signifie que :

    • Les formes ont déjà divergé. Le même concept existe en quatre variantes légèrement différentes, et plus personne ne sait lesquelles sont intentionnelles.
    • Le type honnête est souvent très large. Décrire ce que le code fait vraiment donne des unions de variantes nullables : exact, et pas d’un grand secours.
    • L’échappatoire est toujours disponible. Sous la pression, any fait taire le compilateur et la migration s’arrête à mi-chemin — le pire état possible : le coût de la syntaxe sans le bénéfice de la vérification.
    • Cela entre en concurrence avec le produit. Personne ne planifie un sprint de migration pour un bénéfice difficile à montrer en démonstration.

    Écrits dès le départ, aucun de ces points ne s’applique. Vous ne décrivez pas du code existant : vous décidez des formes pendant que la décision est encore dans votre tête.

    Où le gain arrive en premier

    Les frontières

    Partout où des données entrent dans votre application — réponse d’API, formulaire, paramètre d’URL, valeur stockée — les hypothèses fausses survivent le plus longtemps, parce que la panne apparaît loin de sa cause. Typer la frontière transforme une erreur mystérieuse au fond d’un composant en une erreur de compilation à l’entrée.

    Les états mutuellement exclusifs

    Une requête est en cours, ou réussie avec des données, ou en échec avec une erreur. Trois booléens peuvent exprimer les huit combinaisons, dont la plupart n’ont aucun sens, et chaque composant doit alors deviner dans laquelle il se trouve. Une union de trois variantes rend les états impossibles inexprimables, et le compilateur vous interdira de lire des données depuis celle en échec.

    Tout ce dont dépend le design system

    Noms de variantes, échelle d’espacement et jetons de thème sont des décisions partagées entre designers et développeurs. Un ensemble typé fait qu’une variante supprimée apparaît comme une erreur à chaque appel, au lieu d’un composant qui s’affiche silencieusement sans styles.

    Les coûts, honnêtement

    Ce n’est pas gratuit, et l’argumentaire habituel reste évasif sur les parties pénibles.

    • La qualité des types tiers est inégale. Une définition fausse ou trop permissive est pire que rien, parce que vous lui faites confiance.
    • Les génériques deviennent vite difficiles. Écrire un composant réutilisable et typé est une compétence réellement plus exigeante que sa version non typée, et les messages d’erreur ne sont pas tendres.
    • Il y a une étape de build à garder rapide. La vérification de types ralentit à mesure que le projet grandit et demande d’être traitée comme une infrastructure.
    • Ils vérifient des formes, pas des vérités. Un champ typé comme chaîne peut toujours contenir la mauvaise chaîne. Les types éliminent une catégorie de bugs, pas les bugs.

    Ce dernier point mérite d’être retenu. Les types ne sont pas des tests et ne vérifient pas un comportement. Ils rendent le remaniement sûr, ce qui est un bénéfice différent et cumulatif : les projets qui restent agréables à faire évoluer sont ceux où changer une décision ne demande pas du courage.

    Si vous démarrez quelque chose maintenant

    1. Activez strict dès le premier commit. L’activer plus tard revient à corriger d’un coup toutes les vérifications de nullité, soit exactement la migration que vous vouliez éviter.
    2. Typez d’abord les frontières — réponses d’API, formulaires, données stockées. C’est l’essentiel du bénéfice pour une fraction de l’effort.
    3. Modélisez les états exclusifs par des unions plutôt que par plusieurs booléens.
    4. Traitez any comme un commentaire disant « ce n’est pas terminé », et gardez-le assez rare pour qu’il se remarque en relecture.
    5. Lancez la vérification de types dans l’intégration continue, pas seulement dans l’éditeur, pour qu’un type cassé ne puisse pas être fusionné.

    Rien de tout cela n’exige une grande équipe, un long calendrier ni un plan de migration. Cela exige d’écrire la décision au moment où vous la prenez, le seul moment où elle est bon marché.

    Si vous pesez ce choix pour un produit que vous vous apprêtez à construire, parlez-nous-en.