TypeScript 6 et 7 : une inférence plus intelligente, suivie d’une réécriture basée sur Go
Découvrez comment TypeScript 6 a comblé les lacunes dans l’inférence des clés et modernisé les valeurs par défaut, préparant le terrain pour la réécriture complète du compilateur de TypeScript 7 en Go.
Récemment, TypeScript s’est amélioré sur deux fronts distincts, et ensemble ils racontent une même histoire : le langage devient à la fois plus intelligent et plus rapide. TypeScript 6, sorti en tant que version finale écrite avec le compilateur traditionnel basé sur JavaScript avant le grand changement architectural, s’est concentré sur la correction de défauts persistants liés à l’inférence et sur la modernisation des paramètres par défaut. TypeScript 7 a ensuite pris une mesure plus radicale en réécrivant le compilateur lui-même en Go, visant une vitesse maximale plutôt que de nouvelles syntaxes. En examinant ces deux versions ensemble, on comprend comment l’ensemble outils est parvenu à son état actuel : d’abord en devenant plus précis, puis en gagnant en vitesse de manière significative.
Inférence plus intelligente dans TypeScript 6
Tout ceux qui ont tapé une abréviation de méthode puis vu le paramètre se transformer silencieusement en any savent à quel point les anciennes règles d’inférence de TypeScript pouvaient être frustrantes. TypeScript 6 remédie à ce problème ainsi qu’à quelques autres lacunes d’inférence qui ont poussé les développeurs à chercher des solutions pendant des années.
Auparavant, toute fonction qui faisait référence à this en interne était considérée comme « sensible au contexte », ce qui signifiait que le compilateur omettait complètement l’inférence du type du paramètre — même dans les cas où this n’était jamais réellement utilisé à l’intérieur du corps de la fonction :
// Old behavior: 'user' silently became 'any'
const handlers = {
onSave(user) {
console.log(user.name); // no autocomplete, no error
},
};
Avec TypeScript 6, le compilateur ne considère une fonction comme sensible au contexte que lorsque this est réellement utilisé à l’intérieur d’elle. Sinon, la déduction normale reprend le dessus et le paramètre reçoit son type attendu au lieu de tomber sur any:
// TypeScript 6: 'user' is correctly inferred from context
const handlers: Handlers = {
onSave(user) {
console.log(user.name); // fully typed
},
};
Cela semble être un petit ajustement technique, mais il a un impact considérable sur le développement quotidien, en particulier dans les bases de code React et Next.js où les méthodes d’objet et les gestionnaires d’événements sont omniprésents.
TypeScript 6 intègre également un soutien de premier ordre pour les déclarations using, qui formalisent la gestion explicite des ressources. Au lieu d’encadrer manuellement la logique de nettoyage dans un bloc try/finally, vous pouvez laisser le compilateur gérer automatiquement la libération des ressources une fois que une valeur sort de son champ d’application :
function readConfig() {
using file = openFile("./config.json"); // auto-disposed at scope end
return JSON.parse(file.read());
}
Les importations de sous-répertoires deviennent également plus propres. Le préfixe #/ fonctionne désormais via le champ imports, vous permettant d’éviter de longues chaînes de chemins relatifs ../../../ :
{
"imports": {
"#/*": "./src/*"
}
}
import { formatCurrency } from "#/utils/currency";
// instead of: import { formatCurrency } from "../../../utils/currency";
Divers paramètres par défaut ont également été modifiés. L’option target vise désormais par défaut ES2023 au lieu de l’ancienne norme ES3 ; module prend par défaut la valeur ESNext, et moduleResolution est défini par défaut sur bundler. L’option types est quant à elle définie par défaut sur un tableau vide, ce qui empêche TypeScript de scanner et de charger automatiquement tous les paquets @types qu’il peut trouver. Selon Microsoft, cette dernière modification seule permet d’obtenir des améliorations lors de la compilation allant de 20 à 50 pour cent, ce qui rend utile l’examen de votre fichier tsconfig.json, même si vous n’avez aucun intérêt à adopter de nouvelles fonctionnalités linguistiques.
En somme, les recommandations de TypeScript 6 sont les suivantes : auditez tous les objets riches en méthodes dans votre codebase, car ils pourraient bénéficier gratuitement d’améliorations automatiques en matière de sécurité des types ; utilisez using chaque fois que vous travaillez avec des fichiers, des connexions ou des temporiseurs nécessitant un nettoyage ; ne vous contentez pas d’hériter silencieusement des paramètres par défaut du nouveau compilateur — définissez-les explicitement dans tsconfig.json afin que votre intention soit claire ; et attendez-vous à ce que les définitions de types fournies par des frameworks et des bibliothèques comme React, Redux et les outils Tailwind suivent ces changements au cours des semaines à venir. TypeScript 6 n’est pas une version provisoire — il réduit de manière significative le nombre de surprises liées à l’inférence que vous rencontrez au quotidien, ce qui est en soi une raison suffisante pour mettre à jour.
La réécriture complète en TypeScript 7
Tandis que TypeScript 6 a affiné la manière dont le compilateur gère les types, TypeScript 7 vise quelque chose de plus fondamental : la vitesse d’exécution de l’ensemble de l’écosystème. Microsoft a réécrit entièrement le compilateur, le service linguistique ainsi que les outils associés en Go, remplaçant ainsi l’implémentation JavaScript auto-hébergée qui avait servi TypeScript pendant des années. Il ne s’agit pas d’une simple mise à jour de version — on le décrit comme la plus grande amélioration en termes de performances dans l’histoire du langage.
Tout ceux qui ont déjà regardé le curseur de chargement d’un éditeur en attendant l’apparition d’une erreur de type reconnaîtront précisément le problème que cette réécriture vise à résoudre.
Puisque l’équipe a simplement adapté la logique du compilateur original au lieu de réécrire les règles de vérification des types à partir de zéro, la compatibilité avec le code existant est restée largement intacte tout au long de cette transition.
Les tests de performance publiés par Microsoft donnent une idée de l’ampleur des améliorations. Sur le codebase de VS Code, composé d’environ 1,5 million de lignes, une compilation complète qui prenait auparavant environ 125 secondes se termine désormais en une dizaine de secondes. Le temps nécessaire pour détecter la première erreur de type dans l’éditeur est passé d’environ 17 secondes à moins de 1,5 seconde. L’utilisation mémoire a diminué d’environ 18 %, et les plantages du serveur de langage ont chuté de plus de 60 %. Il ne s’agit pas non plus de chiffres purement synthétiques : des entreprises telles que Slack, Figma, Google, Notion et Vercel ont testé le nouveau compilateur sur de vrais projets en production avant son lancement, et ont constaté que les améliorations persistaient en dehors des tests contrôlés.
Pour les équipes travaillant avec React et Next.js, cela se traduit par des avantages concrets au quotidien. Dans un grand monorepo, l’attente que tsc détecte une incohérence de type pouvait auparavant durer plusieurs secondes ; cette charge supplémentaire diminue considérablement avec le compilateur basé sur Go :
// Before: waiting on tsc to catch this in a large monorepo could take seconds
interface UserCardProps {
name: string;
avatarUrl?: string;
onSelect: (userId: string) => void;
}
function UserCard({ name, avatarUrl, onSelect }: UserCardProps) {
// With TS7's native checker, this feedback loop is nearly instant
return (
<button onClick={() => onSelect(name)} className="rounded-lg p-2 hover:bg-slate-100">
{avatarUrl && <img src={avatarUrl} alt={name} className="h-8 w-8 rounded-full" />}
<span>{name}</span>
</button>
);
}
Les grandes applications Next.js comptant des centaines de composants ne considèrent plus la vérification de types comme le goulot d’étranglement dans les processus CI qu’elle était auparavant. Les projets utilisant de nombreux types génériques, tels ceux qui combinent Tailwind et Redux, bénéficient de compilations incrémentales nettement plus rapides. L’autocomplétion dans l’éditeur, au sein de grands monorepos, est également beaucoup plus réactive.
es5, ainsi que les anciennes paramétrisations de résolution des modules, ne sont plus simplement des avertissements — elles sont considérées comme des erreurs graves. De plus, étant donné que l’API programmatique n’est que partiellement stable dans cette version, tout framework ou outil qui en dépend directement devrait attendre la version TypeScript 7.1 avant de procéder à la mise à niveau.
Rien de tout cela ne nécessite une nouvelle syntaxe ou une grammaire fondamentalement différente — TypeScript 7 existe principalement pour répondre aux plaintes persistantes depuis une décennie concernant les performances du compilateur. Si votre équipe gère un grand ensemble de code React ou Next.js, c’est la version qui permet enfin à tsc de ne plus sembler être un obstacle à surmonter. Comme pour tout changement majeur d’infrastructure, il est judicieux de l’essayer d’abord sur une branche secondaire ; votre pipeline CI vous en remerciera pour cette prudence.
Lectures complémentaires
- La réécriture de TypeScript 7 en Go : quelles conséquences pour la sécurité des types dans React — Découvrez comment le compilateur basé sur Go de TypeScript 7 accélère les builds et améliore l’inférence générique, éliminant les types
anycachés dans les hooks React et JSX.