Décryptage de TypeScript 7.0 : un compilateur 10 fois plus rapide réécrit en Go

TypeScript · Release 7.0

Décryptage de TypeScript 7.0 : un compilateur 10 fois plus rapide réécrit en Go

typescriptTypeScriptpublicationGocompilation parallèleoptimisation des performances

Sources:GitHub Releases + 官方博客 + HN

TypeScript 7.0 marque une refonte architecturale historique. Placée sous le signe de « la vitesse extrême et de la concurrence », cette version voit son compilateur entièrement réécrit depuis JavaScript vers le langage Go. Cette refonte confère à TypeScript les performances d’exécution du code natif ainsi qu’une gestion multithread à mémoire partagée, réduisant les temps de compilation complète d’un facteur 8 à 12 sur les projets réels tout en diminuant substantiellement l’empreinte mémoire. Dans cet article, nous analysons en détail les nouveautés majeures de TypeScript 7.0 ainsi que les bonnes pratiques pour une migration réussie.

Réécriture intégrale en Go et bond en avant des performances

L’évolution la plus fondamentale de TypeScript 7.0 réside dans la refonte de son infrastructure sous-jacente. Pendant de nombreuses années, TypeScript était un compilateur auto-hébergé (self-hosting), écrit directement en TypeScript/JavaScript. Avec la version 7.0, l’équipe de Microsoft a réalisé un portage natif en Go d’une fidélité exceptionnelle.

Ce changement résout enfin les goulots d’étranglement de performance rencontrés sur les projets d’envergure. Lors des tests officiels sur de grands projets open source (tels que VS Code ou Sentry), le temps de compilation est passé de plusieurs centaines de secondes à quelques dizaines, voire quelques secondes seulement, soit un gain de vitesse moyen de l’ordre de 10x. Parallèlement, le pic d’utilisation mémoire est nettement diminué sur l’ensemble du cycle de compilation, préservant de précieuses ressources pour le développement local et les pipelines de CI.

Nouveaux contrôles de concurrence et mode monothread

Tirant parti des mécanismes avancés de concurrence de Go, TypeScript 7.0 exécute désormais en parallèle les phases d’analyse syntaxique (parsing), de vérification des types et de génération de code. De nouveaux paramètres CLI ont été intégrés pour offrir un contrôle précis de ces traitements concurrents.

Le flag --checkers permet de définir le nombre de threads (workers) alloués à la vérification des types (valeur par défaut : 4). Augmenter cette valeur sur les machines dotées de processeurs multicœurs permet de réduire encore davantage les temps de compilation, tandis qu’il est possible de la diminuer dans des conteneurs de CI aux ressources contraintes. De la même manière, le paramètre --builders régit le niveau de parallélisme lors de la compilation d’architectures multi-projets avec Project References.

Par ailleurs, afin de faciliter le débogage ou d’exécuter le compilateur dans des environnements fortement bridés, le nouveau flag --singleThreaded force l’exécution séquentielle de toutes les opérations sur un seul thread.

Refonte du mécanisme de surveillance en mode Watch

Pour les équipes développant en continu avec le mode --watch, les anciennes versions de TypeScript engendraient une charge CPU sensible liée au polling lors de la surveillance d’arborescences massives dans node_modules.

TypeScript 7.0 intègre une nouvelle stratégie de surveillance de fichiers inspirée de l’architecture de @parcel/watcher. En portant directement cette logique au sein de Go, le compilateur dispose d’une détection multiplateforme des modifications de fichiers à très faible coût, sans nécessiter de chaîne d’outils de compilation C++. Les temps de réponse lors du rechargement à chaud (hot reload) et au sein de l’éditeur sur les grands projets frontend atteignent désormais l’échelle de la milliseconde.

Compatibilité de l’écosystème : coexistence via l’alias TypeScript 6

Le compilateur de TypeScript 7.0 ayant entièrement basculé vers Go, il n’expose pas pour l’instant l’ancienne API programmatique utilisée par les outils tiers (une nouvelle API repensée est prévue pour la version 7.1). De ce fait, les outils fortement dépendants de l’API de TypeScript, tels que typescript-eslint, ne peuvent pas s’interfacer directement avec le moteur 7.0.

Afin de garantir une transition fluide, Microsoft propose une approche de coexistence Side-by-Side. En installant le package de compatibilité @typescript/typescript6, un même projet peut exploiter TypeScript 7.0 pour les builds CLI et les services de l’éditeur, tout en permettant aux outils reposant sur l’API de basculer de manière transparente sur le moteur 6.0.

{
  "devDependencies": {
    "typescript": "npm:@typescript/typescript6@^6.0.2",
    "@typescript/native": "npm:typescript@^7.0.2"
  }
}

Prise en charge native d’Unicode dans les types de littéraux de gabarit

Lors de l’inférence de types sur les chaînes de caractères, les précédentes versions de TypeScript suivaient fidèlement l’indexation par unités de code UTF-16 propre à JavaScript. Par conséquent, les paires de substitution (surrogate pairs) comme les émojis étaient tronquées en leur milieu, produisant des caractères corrompus sans signification. Avec TypeScript 7.0, les types de littéraux de gabarit préservent désormais chaque caractère Unicode comme une entité logique indivisible.

type HeadTail<S> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;

type Result = HeadTail<"😀abc">;
// Dans la version 7.0, le résultat déduit est : ["😀", "abc"]
// Dans les versions précédentes, le résultat déduit était : ["\ud83d", "\ude00abc"]

Cette amélioration simplifie considérablement les manipulations de chaînes au niveau du système de types, garantissant une cohérence parfaite avec le comportement à l’exécution des boucles for...of et de la décomposition de tableaux.

Ajustements des spécifications JavaScript et changements cassants

Dans TypeScript 7.0, les règles d’analyse de JSDoc et des fichiers JavaScript classiques ont été durcies, éliminant certains cas particuliers marginaux au profit d’une analyse beaucoup plus rapide. Par exemple, le comportement spécifique du tag @enum a été retiré au profit de déclarations standards, et les annotations de fonctions issues du style Closure Compiler (comme function(string): void) sont abandonnées au profit de la syntaxe fléchée standard de TypeScript (s: string) => void.

De plus, la version 7.0 applique par défaut des paramètres plus stricts (issus des nouvelles normes introduites dans la 6.0 et désormais convertis en erreurs bloquantes) :

  • L’option strict est activée par défaut, et module pointe par défaut vers esnext.
  • rootDir prend par défaut la valeur ./, et types est initialisé par défaut à [] (évitant le chargement implicite de l’ensemble des définitions de types).
  • La prise en charge de target: es5 est définitivement supprimée.
  • Les options baseUrl et moduleResolution: node sont totalement dépréciées ; l’équipe officielle recommande d’adopter les modes nodenext ou bundler combinés aux alias de chemins standards.

Recommandations de migration

Public concernéQuand mettre à jourPoints de vigilance pour la migration
Projets TypeScript pursMise à jour immédiateVérifier la suppression du champ déprécié baseUrl dans tsconfig.json ; configurer explicitement "rootDir": "./src" pour les sources hors racine ; déclarer explicitement les types nécessaires comme "types": ["node"].
Projets JavaScript historiques basés sur JSDocAttendre / Mise à jour prudenteL’analyse de JSDoc est plus rigoureuse dans la 7.0 ; tous les commentaires reposant sur la syntaxe Closure doivent être convertis vers la notation TypeScript standard.
Développeurs de frameworks Vue / Astro / SvelteDifférer ou utiliser une configuration hybrideLes plugins de templates dépendant fortement de l’API interne ne sont pas encore totalement adaptés à la 7.0 dans les éditeurs ; il est conseillé d’attendre la 7.1 ou d’utiliser le mode de coexistence mentionné ci-dessus.
Mainteneurs de bibliothèques et d’outilsTests d’adaptationSi votre package s’appuie sur l’API publique de typescript, invitez vos utilisateurs à installer le package de compatibilité avec alias 6.0 pour éviter toute erreur à l’exécution.

Références