Pourquoi le portage de TypeScript 7 en Go a endommagé les outils de vérification et les outils de développement des frameworks.
Explique pourquoi le compilateur plus rapide de TypeScript 7, basé sur Go, est livré avec une API incompatible, ce qui endommage les outils de vérification, les installations ainsi que les mises à jour de Vue/Svelte dans l’écosystème.
Le compilateur a été livré. L’API qui aurait dû être fournie avec lui ne l’a pas été.
Microsoft a sorti TypeScript 7.0 le 8 juillet 2026, et le titre de l’annonce s’écrivait presque de lui-même : dix fois plus rapide. Le compilateur est passé de JavaScript à Go, fonctionnant sur plusieurs threads, traitant des bases de code qui nécessitaient auparavant deux minutes entières pour être compilées, et les terminant désormais avant même que l’on puisse passer à une autre fenêtre. Presque tous les newsletters relatant cette sortie commençaient par ce même graphique de comparaison.
Puis les développeurs ont réellement exécuté npm install.
Beaucoup d’entre eux se sont retrouvés avec un code binaire rapide mais fonctionnant au-dessus d’une chaîne d’outils défectueuse. Et ces défauts n’étaient pas subtils : les outils de vérification se plantaient déjà lors d’une simple lecture de propriété. Les gestionnaires de paquets rejetaient catégoriquement l’installation en raison d’un déséquilibre dans les plages de dépendances. Les projets Vue et Svelte ne pouvaient absolument pas être mis à jour. Un mois plus tard, la situation reste presque inchangée, et aucune correction n’est prévue pour les versions actuellement programmées.
C’est cette partie de l’histoire qui a été négligée, et c’est elle qui détermine réellement si vous devez procéder à cette mise à jour maintenant.
Le chiffre cité par tout le monde
Il convient d’abord de reconnaître la source des informations, car les améliorations de performance ne sont pas simplement du marketing. Microsoft a publié ses propres chiffres de benchmark dans l’annonce de la version, et ils sont suffisamment détaillés pour être vérifiés.
L’équipe signale des accélérations allant de 8x à 12x pour les builds complètes, et l’utilisation mémoire a même diminué au lieu d’augmenter, ce qui est le contraire de l’équilibre habituel que l’on pourrait s’attendre à voir. Slack a indiqué à Microsoft que le contrôle de type dans leur pipeline CI était passé d’environ sept minutes et demie à un peu plus d’une minute, et que l’expérience d’édition était passée de presque inutilisable à un chargement en quelques secondes. Canva a rapporté que le temps nécessaire pour voir la première erreur dans l’éditeur était passé d’environ 58 secondes à moins de 5.
Ce sont des réalisations techniques réelles, le fruit d’un an de travail acharné. Rien dans ce qui suit ne vient remettre cela en question.
C’était une port, pas une réécriture
Voici le détail technique que la plupart des articles ont négligé, et c’est ce détail qui explique tout le reste.
TypeScript 7 s’agit d’une adaptation, et non d’une réécriture complète à partir de zéro. L’équipe a traduit le compilateur existant, fichier par fichier, de TypeScript en Go, en préservant délibérément la structure et la logique originales afin que le comportement de vérification des types reste identique. Tout ce qui compilait correctement sous 6.0 doit pouvoir se compiler de la même manière sous 7.0. C’est précisément ainsi que Microsoft a réussi à livrer un compilateur de cette envergure sans une longue série de régressions comportementales, ce qui témoigne d’une véritable discipline dans la réalisation de cette adaptation.
Mais un compilateur est en réalité deux produits distincts qui partagent le même nom. Il y a le binaire que l’on exécute, tsc. Et il y a la bibliothèque que d’autres outils intègrent en tant que dépendance. Les linter, les transformateurs de tests, les codemods basés sur l’AST et les vérificateurs de templates n’appellent pas tsc ni ne analysent le texte qu’il affiche. Au lieu de cela, ils importent directement TypeScript, parcourent son arbre syntaxique avec lui et extraitent les informations de type directement du vérificateur.
La portée a transmis fidèlement le premier produit. Elle n’a absolument pas transmis le second.
Le compilateur lui-même a survécu intact. L’API dont dépendent tous les outils associés n’a pas survécu avec lui.
La ligne cachée vers la fin des notes de version
Pour être juste envers Microsoft, cela n’a pas été caché. Si vous lisez l’annonce de la version 7.0, vers les deux tiers du texte, sous une section expliquant comment exécuter 7.0 en même temps que 6.0, on trouve une phrase dont l’ensemble de l’écosystème a parlé tout au long du mois de juillet : TypeScript 7.0 est livré sans API.
C’est un manque important. Microsoft affirme qu’elle travaille sur une nouvelle API et prévoit de la rendre disponible dans la version 7.1. Selon l’équipe, maintenant que le travail de portage est terminé, ils reportent leur attention sur l’ajout de nouvelles fonctionnalités.
Le rythme annoncé est une nouvelle version tous les trois à quatre mois. Si ce calendrier se tient, la version 7.1 devrait sortir vers octobre. C’est tout ce qui est connu pour l’instant — il n’y a pas encore de date confirmée pour la disponibilité effective de l’API de remplacement.
Lisez l’annonce de haut en bas et le schéma deviendra clair. D’abord, on trouve un tableau montrant à quel point 7.0 est plus rapide. Ensuite, des citations élogieuses de grandes entreprises. Ce n’est qu’après que Microsoft mentionne, presque en passant, qu’une partie importante de l’écosystème d’outils ne peut pas encore fonctionner avec cette version.
Cet ordre était un choix éditorial délibéré, et non une tentative de tromper qui que ce soit. C’est aussi pour cette raison que de nombreuses équipes ont découvert le manque d’API à partir d’un journal des erreurs dans leur terminal, plutôt que directement à partir de l’annonce elle-même.
Problème 12518
L’élément le plus utile issu de la semaine de lancement n’était pas un test de performance, mais un rapport de bug.
Le jour où le nouveau compilateur est devenu disponible au public, quelqu’un qui mettait à jour un projet Vite plus React de 6.0.3 à 7.0.2 a soumis le ticket 12518 contre typescript-eslint, accompagné d’une démonstration. Ce dernier décrivait deux échecs distincts.
Le premier consistait en le fait que npm ci refusait complètement d’installer les dépendances, car la métadonnée du paquet typescript-eslint fixait une plage de dépendances compatibles hors de laquelle 7.0.2 se situait. Le second problème, pour ceux qui insistaient malgré tout pour effectuer l’installation, était que ESLint cessait de fonctionner à l’intérieur de typescript-estree lors de la compilation du programme, car le code tentait d’accéder à une propriété de l’API du compilateur qui n’existait plus dans cette version.
Les mainteneurs ont fermé ce ticket. Non pas parce qu’ils s’en fichaient, mais parce qu’il n’y avait rien de concrètement à faire.
Lire cela de manière isolée donne l’impression que c’est une critique dédaigneuse. Ce n’est pas le cas. Les mainteneurs de typescript-eslint n’ont aucun moyen de résoudre ce problème eux-mêmes — le composant dont ils auraient besoin n’a pas encore été publié. Fermer ce ticket n’était qu’une affirmation honnête des faits : le véritable travail doit être effectué côté TypeScript 7.1, et non à l’intérieur du linter. Cela signifie que l’outil TypeScript le plus utilisé dans l’écosystème est actuellement incapable de faire quoi que ce soit concernant sa propre compatibilité.
L’équipe principale d’ESLint a ouvert un ticket correspondant le jour suivant, confirmé son intention de s’y atteler, mais se trouve également bloquée en attendant ce même composant manquant. Les mainteneurs des outils Vue se trouvent dans la même situation. Tous ceux qui utilisent ces outils sont bloqués en raison de cette dépendance non encore publiée.
L’impact
Tout package qui importe typescript et accède à ses fonctionnalités internes est exposé à ce problème. Plus concrètement :
- typescript-eslint, ainsi que toutes les règles de vérification basées sur lui et prenant en compte les types. Cela provoque une erreur évidente, soit au moment de l’installation, soit dès la première exécution — vous ne pourrez pas la manquer.
- ts-jest et tout transformateur basé sur des appels au compilateur interne. Cela entraîne une erreur plus discrète, se manifestant par des erreurs de transformation confuses plutôt qu’une panne d’installation, ce qui est peut-être pire car cela ressemble à un problème de configuration des tests plutôt qu’à une incompatibilité de version.
- ts-morph et tous les codemods personnalisés basés sur lui. C’est la catégorie la plus risquée. L’inspection approfondie des types peut se dégrader silencieusement, produisant des résultats légèrement incorrects au lieu d’une panne évidente. Faites une vérification approfondie avant d’exécuter quoi que ce soit de destructeur sur une base de code.
ts-loader continuent d’utiliser l’API obsolète. Une personne ayant commenté l’annonce a résumé l’état d’esprit général : envie de mettre à jour, mais comme la plupart des projets utilisent encore webpack et qu’aucune API compatible pour les chargeurs n’existe encore, tout le monde attend la version 7.1.Examinez de près ce qui figure sur cette liste. Aucun outil n’y est spécialisé ou exotique — il s’agit de l’ensemble d’outils par défaut d’une équipe front-end typique travaillant aujourd’hui.
Le compilateur lui-même est stable. L’écosystème qui l’entoure, en revanche, ne l’est pas. Ce sont deux états de version distincts qui partagent le même numéro de version.
La solution de Microsoft : installer deux compilateurs en même temps
Microsoft a anticipé ces problèmes et a créé une solution de contournement plutôt que de laisser les équipes improviser. Ils ont publié @typescript/typescript6, un paquet de compatibilité qui fournit un exécutable tsc6 et restaure l’accès à l’API de version 6.0. Cela permet au compilateur ancien et au nouveau de coexister sans que l’un ne vienne entrer en conflit avec le nom binaire de l’autre.
La raison pour laquelle cette solution de contournement est nécessaire est que des outils tels que typescript-eslint résolvent TypeScript en fonction de son nom de package via une dépendance pair. Par conséquent, la correction recommandée consiste à utiliser un alias npm pour rediriger ce nom.
La configuration complète avec deux compilateurs se présente comme suit :
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
Avec cela en place, votre linter, votre transformateur de tests et vos codemods continuent d’importer typescript comme d’habitude et reçoivent transparentement la version 6.0 en arrière-plan. En même temps, l’exécution de npx tsc fait référence à la version 7.0, vous permettant ainsi de bénéficier des gains de vitesse là où c’est le plus important : dans votre éditeur et lors des tests en continu.
Cela fonctionne, et il convient de le reconnaître : il s’agit d’une solution bien conçue, décrite dans l’annonce officielle plutôt que de quelque chose que la communauté a dû déduire par ingénierie inverse.
Néanmoins, il s’agit toujours de deux installations distinctes de compilateurs coexistant dans un même node_modules, résolues grâce à un alias dont chaque nouveau membre de l’équipe devra être informé, ainsi que d’une configuration qu’il faudra finalement modifier une fois la version 7.1 réellement disponible. Appelons les choses par leur nom : une dette technique sans date d’échéance définie.
Le deuxième piège, pour ceux qui ont sauté la version 6.0
En plus de l’API manquante, il existe un autre obstacle majeur pour toute équipe qui est passée directement de la version 5.x sans passer par 6.0 d’abord.
TypeScript 7.0 adopte pleinement les paramètres par défaut introduits par 6.0, et chaque avertissement de dépréciation généré par 6.0 devient une erreur fatale dans 7.0. Tout cela entre en vigueur d’un coup :
strictest désormais activé par défaut.modulea désormais pour valeur par défautesnext.
rootDir a pour valeur par défaut ./ au lieu d’être déduite automatiquement ; par conséquent, si votre tsconfig.json se trouve en dehors de src, vous devez le spécifier explicitement, sinon le compilateur interprétera incorrectement la structure de vos sources.types prend par défaut la valeur d’un tableau vide au lieu de charger tout le contenu. Si votre code dépend de variables globales provenant de paquets @types installés, vous devez soit nommer ces paquets explicitement, soit rétablir le comportement ancien en utilisant ["*"].target: es5, downlevelIteration, moduleResolution: node, baseUrl, ainsi que les modes de modules amd, umd et systemjs. L’utilisation de l’une d’entre elles provoque désormais une erreur de compilation, point final.Dans cette liste, l’équipe identifie rootDir et types comme les deux modifications susceptibles de prendre les utilisateurs par surprise, ce qui correspond à ce que l’on observe en pratique. Dans les deux cas, des erreurs abondent dans le terminal, donnant l’impression que c’est le compilateur lui-même qui est défectueux, au lieu de signaler simplement qu’une valeur par défaut a été modifiée. C’est précisément ce genre de confusion qui conduit à considérer cela comme un bug du compilateur plutôt qu’à le résoudre par une simple modification dans la configuration.
Il y a également un changement plus subtil destiné à ceux qui effectuent des manipulations de chaînes au niveau du type. L’inférence de type des littéraux de template compte désormais un caractère tel qu’un emoji comme une seule unité, au lieu de le diviser en ses deux unités de code UTF-16. C’est un modèle plus intuitif pour la plupart des cas d’usage, mais c’est un changement brisant pour tout type d’aide de style Length personnalisé qui comptait intentionnellement les unités de code UTF-16 plutôt que les caractères visibles.
En résumé : si vous utilisez encore une version 5.x, ne passez pas directement à 7.0. Passez d’abord par 6.0. Cette version intermédiaire existe spécifiquement pour répartir cet ensemble de changements brisants sur deux mises à jour plus petites, au lieu de vous les imposer toutes d’un coup.
Pour qui cette version a-t-elle vraiment été conçue ?
C’est le détail qui mérite d’être examiné un instant.
Regardez la liste des organisations qui ont testé TypeScript 7 avant sa disponibilité générale et ont fourni des commentaires pour l’annonce : l’équipe de VS Code, les produits Office, Teams, Power BI de Microsoft, ainsi que les groupes Loop et Xbox, en plus de Bloomberg, Canva, Figma, Google, Linear, Miro, Notion, Sentry, Slack et Vercel. Il s’agit de bases de code comptant des millions de lignes, soutenues par des équipes dédiées à l’infrastructure de compilation, qui ont exécuté des versions préliminaires pendant des mois et rapporté les problèmes aux développeurs avant le lancement.
Pour des organisations de cette envergure, ce nouveau dépôt modifie réellement la manière de travailler, et les chiffres le confirment. L’équipe des News Services de Microsoft indique économiser 400 heures par mois, qui étaient auparavant consacrées à l’attente des processus de compilation. Lorsqu’une simple vérification de type prenait sept minutes, en réduire le temps d’environ huit fois transforme profondément le rythme quotidien d’un ingénieur.
Comparez maintenant cela à une startup de cinq personnes utilisant Nuxt avec un outil de vérification syntaxique prenant en compte les types. Leur temps de vérification des types était déjà réduit à 9 secondes. La mise à niveau leur permet d’économiser environ 8 secondes, mais en contrepartie entraîne des problèmes avec le pipeline de vérification syntaxique, un outil de vérification des templates Vue qui ne fonctionne tout simplement pas, ainsi qu’une solution temporaire via des alias dans package.json que le prochain membre de l’équipe devra lui expliquer.
L’avantage en termes de vitesse augmente avec la taille de votre base de code. En revanche, les problèmes causés ne varient pas du tout : il s’agit d’un coût fixe, quel que soit le nombre de fichiers dans votre projet, qu’il s’agisse de dix ou de dix millions.
Rien de tout cela ne signifie une mauvaise intention. C’est simplement ce qui se produit lorsque un projet est optimisé en fonction des retours qu’il peut réellement observer. Les gros bases de code d’entreprise faisaient partie du programme de prévisualisation, ce qui permettait de détecter et d’évaluer leurs problèmes bien avant le lancement. Les mainteneurs de l’écosystème — principalement des volontaires travaillant sur des outils de vérification, des intégrations IDE et des outils de compilation — se trouvaient dans une situation où ils n’avaient pas voix au chapitre, et ce qu’ils recevaient en retour n’était qu’un correctif de compatibilité ainsi que la promesse que les problèmes seraient résolus dans la version 7.1.
Une base de code volumineuse transforme cette mise à jour en une véritable aubaine. Une base de code plus petite, quant à elle, doit payer le même coût fixe pour un bénéfice bien moindre. Cet déséquilibre est l’essentiel de cette situation.
Vérification de la prêté à l’emploi, à ce jour
Un mois après la disponibilité générale, voici à peu près où en sont les choses.
Si vous envisagez ce changement, la solution la moins risquée consiste à exécuter 7.0 en tant que deuxième tâche de vérification de types non bloquante dans le CI, en parallèle de celle que vous avez déjà. Cela vous fournira des données temporelles réelles et un sentiment de confiance, sans pour autant faire dépendre votre build d’7.0. Lorsque les deux tâches resteront opérationnelles pendant environ une semaine, vous pourrez alors passer à l’autre solution.
Il n’y a aucun avantage à être un adopteur précoce dans ce cas, il est donc utile de connaître malgré tout les paramètres de réglage disponibles : le flag --checkers contrôle le nombre d’ouvriers de vérification de types exécutés en parallèle, avec une valeur par défaut de 4. Sur un exécutant CI aux ressources limitées, il est généralement plus judicieux de réduire ce nombre à 1 ou 2 plutôt que de conserver la valeur par défaut.
Réproduire le problème en environ cinq minutes
Rien de tout cela ne doit être accepté à la légère, et il ne le devrait pas — l’échec est suffisamment mineur et rapide pour être déclenché délibérément sur un projet de test temporaire, avant même d’ toucher à quoi que ce soit qui vous importe réellement.
Commencez par un squelette Vite React-TypeScript vierge, ajoutez une configuration ESLint sensible aux types, puis essayez d’imposer le compilateur plus récent à la place :
npm create vite@latest ts7-probe -- --template react-ts
cd ts7-probe
npm install
npm install -D typescript-eslint eslint
npm install -D typescript@7
La plupart des gens se heurtent à un problème dès le moment de l’installation. Le paquettypescript-eslint publié définit une plage de dépendance équivalente qui ne dépasse pas la version 6.1.0, ce qui fait que npm rejette immédiatement la résolution, affichant une erreur ERESOLVE au lieu d’un avertissement léger. Or, c’est en réalité le mode d’erreur le plus indulgent.
Un résultat encore plus problématique apparaît si vous forcez l’installation en ignorant le conflit. Avec ces paquets incompatibles en place, l’exécution de lint provoque une panne au sein de typescript-estree lors de la compilation du programme, en raison d’un accès à une propriété qui ne correspond plus à rien :
TypeError: Cannot read properties of undefined (reading 'Cjs')
at .../@typescript-eslint/typescript-estree/dist/create-program/shared.js
Remarquez ce que ce message omet de mentionner. Il ne parle jamais de TypeScript 7, ne signale jamais une incompatibilité de version, et ne dit pas « configuration non prise en charge ». Il s’agit d’une panne interne brute — ce qui correspond exactement à la plainte soulevée dans le ticket 12518 : le rapporteur demandait une erreur de compatibilité claire et lisible par un humain, plutôt qu’un traceur d’exception, et à ce jour cette demande reste en attente.
Appliquez maintenant la solution de contournement basée sur les alias décrite précédemment et exécutez à nouveau les mêmes commandes. Lint fonctionne à nouveau, car il communique discrètement avec TypeScript 6.0 en arrière-plan, tandis que npx tsc seul continue de faire appel à la version plus rapide 7.0.
Puisque vous avez configuré les choses de cette manière, il vaut la peine de mesurer le temps de compilation sous les deux versions. C’est ce chiffre, et non celui d’un autre test de performance, qui devrait guider votre décision — et il sera presque certainement bien moins élevé que les valeurs affichées par VS Code, simplement parce que votre base de code n’a pas deux millions de lignes.
Ce que j’en retire
Ce qui rend TypeScript 7 un cas particulier, c’est que deux interprétations contradictoires en sont toutes deux exactes, alors que la plupart des analyses n’en ont retenu qu’une seule.
C’est une véritable œuvre d’ingénierie de compilateur qui permet aux équipes de gagner des heures réelles chaque semaine, autrefois perdues à cause de temps de compilation trop longs. Il s’agit également d’une version qui n’a livré que la moitié de ce dont elle avait besoin, facteur révélé en profondeur dans l’annonce, laissant les conséquences aux mainteneurs qui n’avaient aucun pouvoir sur le calendrier de publication.
Ce qui aurait été utile — et ce qui n’a pas été clairement indiqué au lancement —, c’est une simple phrase en haut : cette version est prête pour votre pipeline de compilation, pas pour vos outils, et voici exactement ce que cela signifie pour vous. Cette phrase était techniquement présente, mais elle était simplement cachée bien après le tableau des benchmarks.
La version 7.1 vise à combler réellement cette lacune. Jusqu’à ce que cela soit fait, l’approche sensée est restreinte : profiter de la vitesse là où cela ne coûte rien, c’est-à-dire dans votre éditeur et dans les tests continus, et laisser inchangées toutes les outils qui importent encore directement le compilateur.
Lectures complémentaires
- Le rôle de pont de TypeScript 6 sur la voie vers un compilateur natif TS 7 — Découvrez comment TypeScript 6 met à jour les configurations par défaut, la résolution des modules et la syntaxe d’import afin de préparer les bases de code pour le compilateur TypeScript 7, plus rapide et basé sur Go.