Accueil / Articles

TypeScript 7 et le port Go : des compilations plus rapides, une meilleure gestion de la mémoire et des retours en temps réel depuis l’éditeur.

TypeScript 7 remplace le compilateur par un moteur natif Go. Des compilations en parallèle, une consommation de mémoire réduite, un nouveau serveur de langage, ainsi que des précautions à prendre avant la migration.

Éditeur : REACTAPP.TOP8 min de lecture1789 mots

Sources: TypeScript 7 Is Here — And It Changes Much More Than the Compiler

Tout ceux qui utilisent TypeScript depuis des années connaissent ce rythme : on écrit du code, l’éditeur l’analyse un moment, TypeScript traite le projet, puis tsc s’exécute, laissant encore de l’attente. Dans un grand monorepo, cette pause est suffisamment longue pour aller chercher un café. Rien de tout cela ne signifie pour autant que l’outil est mal conçu. Son système de types et ses outils linguistiques se sont suffisamment renforcés pour gérer des bases de code très volumineuses, et c’est précisément pour cela qu’il est devenu si central dans le monde JavaScript. Mais cette puissance a un prix : à mesure que les projets s’agrandissent, le compilateur et le serveur de langage deviennent un goulot d’étranglement en termes de performance.

TypeScript 7.0 est la réponse de Microsoft, et ce qui est notable, c’est que le principal changement ne concerne ni un nouvel opérateur, ni un mot-clé, ni une astuce de syntaxe. Il s’agit plutôt du moteur qui le sous-tend. Le compilateur de TypeScript était auparavant écrit en TypeScript, une structure récursive agréable qui fonctionnait bien, mais qui obligeait le compilateur à fonctionner au sein du modèle de temps de exécution de JavaScript. Pour la version 7, Microsoft a porté le compilateur sur Go, ce qui a permis d’obtenir une implémentation native conçue pour tirer parti du matériel moderne et du parallélisme.

C’est là l’essentiel à comprendre concernant cette version. TypeScript 7 n’est pas avant tout un nouveau langage, mais plutôt un nouveau moteur pour le langage que les gens utilisent déjà, et cette perspective explique presque tout le reste à son sujet.

Les chiffres relatifs à la vitesse

Le chiffre clé indique une vitesse dix fois supérieure. Les benchmarks de Microsoft montrent que les compilations complètes s’exécutent généralement 8 à 12 fois plus rapidement, en fonction du projet, et ces résultats proviennent de grands bases de code réels et non de microbenchmarks synthétiques.

Le temps de compilation n’est même pas le résultat le plus frappant, car le serveur de langage accélère également les opérations. Dans l’exemple de Microsoft utilisant la base de code de VS Code, l’ouverture d’un fichier contenant une erreur est passée d’environ 17,5 secondes avant l’apparition de la première erreur à moins de 1,3 seconde. Cela change complètement l’expérience d’utilisation, et dans les grands dépôts, c’est bien plus important que de réduire de quelques centaines de millisecondes le temps de compilation en production.

Utilisation de chaque cœur

Les machines modernes disposent de nombreux cœurs, tandis que tsc fonctionnait historiquement avec un seul. TypeScript 7 en tire beaucoup mieux parti : le parsing, la vérification des types et l’émission des résultats peuvent s’exécuter en parallèle lorsque c’est possible. Il ajoute également quelques paramètres expérimentaux :

--checkers
--builders
--singleThreaded

Les deux premiers offrent un contrôle plus fin sur la manière dont le travail en parallèle est divisé, et --singleThreaded désactive le parallélisme lorsque c’est nécessaire, par exemple lors du débogage du comportement du compilateur ou en environnement restreint.

Les monorepos en tireront le plus de bénéfices. Imaginez un répertoire contenant un dossier apps :

apps/
  web/
  admin/
  mobile/

et un répertoire de paquets :

packages/
  ui/
  api/
  config/
  utils/
  domain/

TypeScript était auparavant utilisé pour effectuer une grande quantité de tâches séquentielles au sein de ce graphe de dépendances. Avec la version 7, davantage de ces tâches peuvent être exécutées en même temps. Ainsi, il ne s’agit pas simplement du fait que le compilateur est plus rapide : il peut enfin exploiter pleinement le matériel sur lequel il tourne.

Mémoire

Les performances ne dépendent pas uniquement du temps CPU. Les grands projets TypeScript peuvent consommer plusieurs gigaoctets de RAM, surtout lorsque le serveur de langage fonctionne en même temps qu’un éditeur, un navigateur, Docker et des serveurs de développement. Les benchmarks publiés par Microsoft montrent une réduction de la consommation mémoire allant de 6 % à 26 % pour plusieurs projets de grande taille :

  • Bluesky : environ 26 % de moins
  • VS Code : environ 18 % de moins
  • tldraw : environ 15 % de moins
  • Playwright : environ 11 % de moins

À côté d’une vitesse de compilation dix fois supérieure, ce qui peut sembler modeste, toute personne ayant observé la mémoire d’un ordinateur portable s’épuiser dans un grand monorepo comprend sa valeur.

Un nouveau serveur de langage

La grande partie de l’attrait de TypeScript ne provient d’ailleurs jamais de tsc. Il vient de l’éditeur : complétions, affichage des informations de type en survol, saut vers la définition, liste de toutes les références, renommage d’un symbole partout, affichage des erreurs en ligne et corrections en un clic. Une grande partie de ce qui caractérise le développement JavaScript moderne repose sur cela.

TypeScript 7 intègre un nouveau serveur de langage basé sur le Language Server Protocol, utilisant une implémentation native et le multithreading. L’équipe continue d’en enrichir les fonctionnalités : les lentilles de code, les suggestions intégrées, l’highlighting sémantique, le tri des importations et la suppression des importations inutilisées sont déjà disponibles, ainsi que les importations automatiques, la fonctionnalité « aller à la définition source » et l’édition liée JSX avec complétions de balises. L’objectif dépasse simplement un tsc plus rapide : tout le processus, de la saisie au retour d’information, devient plus rapide, et c’est sans doute là la véritable avancée.

Résultat déterministe sous parallélisme

Un changement moins spectaculaire mais techniquement intéressant : TypeScript gère de nombreuses tâches internes liées aux types, aux symboles, aux unions et aux déclarations. Lorsque plusieurs processus s’exécutent en même temps, l’ordre de création des objets internes peut varier, ce qui peut modifier les IDs internes et donc altérer l’ordre des déclarations générées.

TypeScript 7 gère ce problème en organisant les éléments de manière déterministe à partir du contenu des objets internes, plutôt qu’en se fiant à l’ordre dans lequel ils sont rencontrés. Prenons cette fonction :

function foo(condition: boolean) {
  return condition ? 100 : 500;
}

Cela peut produire une déclaration comme celle-ci :

export declare function foo(
  condition: boolean
): 100 | 500;

Et l’ordre de l’union reste stable, quel que soit le résultat du travail en parallèle. La plupart des développeurs ne s’en apercevront pas, mais c’est précisément cette conception technique qui rend un compilateur hautement parallèle fiable.

Pas une version fonctionnelle

Tout ceux qui s’attendaient à quelque chose comme cela :

type NewSuperPower<T> = ...

Une multitude de nouvelles fonctionnalités linguistiques pourrait faire que TypeScript 7 paraisse décevant au premier abord. La plupart des efforts ont été consacrés à l’infrastructure plutôt qu’à de nouvelles capacités du système de types. L’équipe a passé des années à jeter les bases de la prochaine génération de TypeScript, et elle existe désormais. Le plan de développement vise désormais des fonctionnalités supplémentaires, une meilleure ergonomie, d’autres améliorations de performance ainsi qu’une nouvelle API de compilateur après 7.0. Cette version se présente davantage comme le début d’une nouvelle ère que comme la fin de la précédente.

Précautions à prendre pour les concepteurs d’outils

C’est ici que les choses deviennent intéressantes pour ceux qui créent des outils. TypeScript 7.0 ne vient pas avec l’ancienne API de compilateur, et l’équipe prévoit que 7.1 en introduira une nouvelle. C’est un point important, car une grande partie de l’écosystème ne se contente pas d’exécuter tsc : les analyseurs de code, les compilateurs de frameworks, les services linguistiques et les outils de construction communiquent avec TypeScript de manière programmée.

C’est l’une des raisons pour lesquelles TypeScript 6 et 7 devront peut-être coexister pour l’instant. Microsoft a introduit @typescript/typescript6 afin de faciliter la transition, permettant ainsi à un projet de conserver la version 6 pour les outils qui ont encore besoin de son API, tout en utilisant séparément le compilateur de la version 7. Une mise à jour du compilateur n’est pas toujours aussi simple que de modifier une seule ligne :

{
  "devDependencies": {
    "typescript": "^7.0.0"
  }
}

Dans les grands écosystèmes, le compilateur constitue une infrastructure, et toute infrastructure présente des dépendances.

Un autre obstacle concerne les frameworks et outils qui intègrent TypeScript au sein de leurs propres pipelines de compilation ou de services linguistiques. Les équipes de Vue, MDX, Astro, Svelte et Angular indiquent que le support pour le nouveau design des services linguistiques est encore en cours de développement, et c’est là encore l’absence d’une API programmative stable qui en est la raison. Une application simple basée sur React et TypeScript peut être migrée sans trop de difficultés. En revanche, une intégration complexe avec un framework, un plugin de compilateur ou un plugin de service linguistique présente des défis plus importants. Il est donc conseillé de vérifier la situation avant de mettre à jour tout grand répertoire de production.

TypeScript 6 en tant que tremplin

TypeScript 6 n’a jamais été simplement la version qui a précédé 7. Il a été conçu délibérément comme un pont entre les versions. Plusieurs anciennes options de compilateur y ont été marquées comme obsolètes et ont complètement disparu dans 7 ; par conséquent, l’équipe recommande de les supprimer avant ce passage à la nouvelle version. Utiliser la version intermédiaire, comme indiqué ci-dessous, est préférable à considérer 7 comme une mise à jour indépendante :

TypeScript 5.x
      ↓
TypeScript 6
      ↓
TypeScript 7

Tous les avertissements de dépréciation générés par un projet sous TypeScript 6 méritent une attention particulière. Ce sont en fait des notifications de migration envoyées depuis l’avenir.

Pourquoi le cycle de retour d’information est important

TypeScript disparaît après compilation, ce qui fait que les développeurs frontend le considèrent rarement comme faisant partie du temps de exécution de l’application. Pourtant, il influence fortement ce temps de exécution. Chaque fois qu’un éditeur traverse un cycle comme celui-ci :

type something
↓
autocomplete appears
↓
you navigate to a definition
↓
you rename a symbol
↓
you save
↓
CI runs
↓
the project gets type-checked

TypeScript est toujours impliqué, et son rôle s’accroît à mesure que les applications évoluent. Un retard de 100 ms n’a pas d’importance, mais un retard de 10 secondes en a ; une attente de 30 secondes modifie la façon dont une personne travaille, tandis qu’une vérification de type en CI d’une durée de cinq minutes affecte le fonctionnement de toute une équipe. La principale caractéristique de TypeScript 7 n’est donc pas une compilation dix fois plus rapide, mais un intervalle plus court entre l’écriture du code et la confirmation de son correctitude.

Essayer

Pour un nouveau projet, TypeScript 7 mérite clairement d’être évalué. Pour un projet existant, une approche plus mesurée convient mieux. Commencez par l’installer en tant que dépendance de développement :

npm install -D typescript@7

Ensuite, effectuez une vérification de type sans émettre de sortie :

npx tsc --noEmit

et examinez les résultats en analysant ces domaines :

  1. Erreurs de compilation
  2. Configuration obsolète
  3. Compatibilité des outils de construction
  4. Intégration d’ESLint
  5. Intégration du framework
  6. Comportement de l’IDE
  7. Performance du CI
  8. Consommation de mémoire

Dans un grand monorepo, effectuez des benchmarks avant et après, en utilisant quelque chose comme :

time npx tsc --build

Et comparez le résultat avec la version actuelle de TypeScript. Le chiffre final ne doit pas être le seul critère à considérer. C’est l’ensemble de l’expérience de développement qui compte.

Reconstruire les fondations

TypeScript 7 se distingue dans les outils de développement frontend parce que l’équipe a évité l’approche habituelle consistant à ajouter davantage de fonctionnalités à l’architecture existante, choisissant plutôt de reconstruire les bases. Le langage lui-même n’avait pas besoin d’être repensé, mais l’infrastructure, si. Le moment choisi est également judicieux : avec des projets JavaScript de plus en plus importants, des monorepos de plus en plus courants, des API sécurisées par types partout, des éditeurs plus intelligents, des outils de codage basés sur l’IA cherchant désespérément des données sémantiques, et des développeurs exigeant des réponses quasi instantanées. Un compilateur suffisamment rapide pour une application de 2015 ne suffira pas nécessairement pour gérer un monorepo de 2026.

En termes simples, cette version reconnaît que le design ancien fonctionnait bien, mais que les logiciels modernes en ont dépassé les limites. Au lieu d’abandonner un système de types déjà apprécié des développeurs, l’équipe a reconstruit ce qui se trouve en arrière-plan. C’est pourquoi cette version est plus importante que ne le laisse supposer sa liste de fonctionnalités visibles. Il s’agit d’une base pour l’évolution future de TypeScript ainsi que d’un outil tsc plus rapide. Si les améliorations promises se répercutent sur l’ensemble de l’écosystème, les fonctionnalités les plus intéressantes de TypeScript pourraient même ne pas figurer dans la version 7. Ce sont peut-être celles qui ne deviendront pratiques que parce que la version 7 est suffisamment rapide pour les développer.

Le titre principal est « dix fois ». Ce qui se cache derrière, c’est le parallélisme, l’exécution native, une consommation de mémoire réduite, un nouveau serveur de langage, des résultats de compilation déterministes et des bases pour des outils futurs. Pour quiconque gère de grandes applications TypeScript, cela vaut sans doute plus que simplement une autre utilité de type.