Loin d'être une simple mise à jour incrémentale, cette version marque un tournant majeur dans l'histoire du langage : c'est la dernière version basée sur le compilateur JavaScript historique. La prochaine itération, TypeScript 7.0, reposera sur un tout nouveau compilateur écrit en Go, tirant parti du code natif et du multi-threading à mémoire partagée pour des performances radicalement supérieures.
TypeScript 6.0 joue donc un rôle de pont entre l'ancien et le nouveau monde. La majorité des changements visent à préparer la transition vers la version 7.0, mais cette release apporte aussi son lot de nouvelles fonctionnalités et d'améliorations concrètes. Faisons le tour complet.
Installer TypeScript 6.0
L'installation se fait classiquement via npm :
npm install -D typescriptSi vous parvenez à adopter TypeScript 6.0 sans difficulté, l'équipe vous encourage fortement à tester dès maintenant les previews natives de TypeScript 7.0, disponibles sur npm et dans Visual Studio Code.
Nouvelles fonctionnalités
Moins de sensibilité au contexte sur les fonctions sans this
TypeScript sait inférer le type des paramètres d'une fonction à partir du contexte. Par exemple, dans un appel générique, il peut déduire le type d'un callback à partir d'un autre argument. Cependant, un comportement historique posait problème : les fonctions écrites en syntaxe méthode (par opposition aux arrow functions) étaient considérées comme « contextuellement sensibles » à cause de leur paramètre implicite this, même lorsqu'elles ne l'utilisaient jamais.
Concrètement, cela pouvait entraîner des erreurs d'inférence surprenantes lorsqu'on inversait l'ordre des propriétés d'un objet littéral passé en argument :
// Avant TS 6.0, cette variante produisait une erreur
callIt({
consume(y) { return y.toFixed(); }, // erreur : 'y' is of type 'unknown'
produce(x: number) { return x * 2; },
});TypeScript 6.0 corrige cela : si une fonction n'utilise jamais this, elle n'est plus considérée comme contextuellement sensible, ce qui améliore l'inférence de types dans de nombreux cas courants. Cette amélioration a été contribuée par Mateusz Burzyński.
Imports de sous-chemins commençant par #/
Node.js supporte les subpath imports, qui permettent de définir des alias internes dans un package via le champ imports du package.json. Jusqu'ici, il était impossible de commencer un alias par #/ directement, ce qui forçait l'utilisation de préfixes un peu artificiels comme #root/.
Node.js a récemment ajouté le support du préfixe #/, et TypeScript 6.0 le prend désormais en charge avec les options nodenext et bundler pour --moduleResolution :
{
"name": "my-package",
"type": "module",
"imports": {
"#/*": "./dist/*"
}
}Les développeurs habitués à @/ dans les bundlers retrouveront un schéma familier et standardisé.
Combinaison de --moduleResolution bundler avec --module commonjs
Auparavant, --moduleResolution bundler ne fonctionnait qu'avec --module esnext ou --module preserve. Avec la dépréciation de --moduleResolution node, cette nouvelle combinaison avec CommonJS devient le chemin de migration le plus naturel pour de nombreux projets.
Le flag --stableTypeOrdering
C'est un ajout important pour la transition vers TypeScript 7.0. Actuellement, TypeScript assigne des identifiants internes aux types dans l'ordre où ils sont rencontrés, et utilise ces identifiants pour trier les types union. Cela signifie que l'ajout d'une simple déclaration peut modifier l'ordre d'affichage d'un type union dans les fichiers de déclaration.
TypeScript 7.0, grâce à son architecture parallèle, adopte un algorithme de tri déterministe basé sur le contenu des types. Le flag --stableTypeOrdering permet d'activer ce même comportement dans la version 6.0, facilitant ainsi la comparaison des sorties entre les deux versions. Attention toutefois : ce flag peut entraîner un ralentissement de 25 % du type-checking selon les projets. Il est conçu comme un outil de diagnostic, pas comme une option permanente.
Option es2025 pour target et lib
TypeScript 6.0 ajoute le support de la cible es2025. Bien qu'ES2025 n'introduise pas de nouvelles fonctionnalités syntaxiques JavaScript, cette option apporte de nouveaux types pour les API intégrées et déplace certaines déclarations de esnext vers es2025, notamment Promise.try, les méthodes d'itérateurs et les méthodes de Set.
Types pour l'API Temporal
La proposition Temporal, très attendue, a atteint le stade 4 et fait désormais officiellement partie du standard ECMAScript. TypeScript 6.0 inclut les types intégrés pour l'API Temporal, accessible via --target esnext ou "lib": ["esnext"] :
let yesterday = Temporal.Now.instant().subtract({ hours: 24 });
let tomorrow = Temporal.Now.instant().add({ hours: 24 });
console.log(`Hier : ${yesterday}`);
console.log(`Demain : ${tomorrow}`);Temporal est déjà utilisable dans plusieurs runtimes. La documentation complète est disponible sur MDN.
Types pour les méthodes « upsert » (getOrInsert)
La proposition ECMAScript « upsert » a atteint le stade 4 et introduit deux nouvelles méthodes sur Map et WeakMap : getOrInsert et getOrInsertComputed. Ces méthodes simplifient un pattern extrêmement courant :
// Avant
let strictValue;
if (compilerOptions.has("strict")) {
strictValue = compilerOptions.get("strict");
} else {
strictValue = true;
compilerOptions.set("strict", strictValue);
}
// Après, avec getOrInsert
let strictValue = compilerOptions.getOrInsert("strict", true);getOrInsertComputed accepte un callback, utile lorsque la valeur par défaut est coûteuse à calculer.
RegExp.escape
La proposition RegExp Escaping a atteint le stade 4 et introduit RegExp.escape(), une fonction qui échappe les caractères spéciaux dans une chaîne destinée à être utilisée dans une expression régulière :
const escapedWord = RegExp.escape("hello (world)");
// Produit : "hello \\(world\\)"Disponible dans la lib es2025.
dom inclut désormais dom.iterable et dom.asynciterable
Auparavant, il fallait ajouter explicitement dom.iterable à la configuration lib pour itérer sur des collections DOM comme NodeList. Ce n'est plus nécessaire : dom seul suffit désormais, puisque tous les navigateurs modernes supportent ces capacités depuis longtemps.
// Avant : nécessitait "lib": ["dom", "dom.iterable"]
// Maintenant : "lib": ["dom"] suffit
for (const element of document.querySelectorAll("div")) {
console.log(element.textContent);
}Changements de valeurs par défaut
TypeScript 6.0 modernise considérablement ses valeurs par défaut. Voici ce qui change :
strict passe à true par défaut. La grande majorité des nouveaux projets activaient déjà le mode strict. Si votre projet en dépendait, vous devrez explicitement déclarer "strict": false.
module passe à esnext par défaut. ESM est désormais le format dominant.
target passe à la version ES la plus récente supportée (actuellement es2025), reflétant la réalité des runtimes evergreen.
noUncheckedSideEffectImports passe à true pour mieux détecter les fautes de frappe dans les imports à effets de bord.
libReplacement passe à false pour de meilleures performances par défaut.
rootDir passe à .
Auparavant, rootDir était inféré à partir du répertoire commun de tous les fichiers source. Désormais, il correspond par défaut au répertoire contenant le tsconfig.json. Si vos fichiers source sont dans un sous-dossier (typiquement src/), vous devrez l'indiquer explicitement :
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["./src"]
}types passe à []
C'est probablement le changement qui affectera le plus de projets. Auparavant, TypeScript incluait automatiquement tous les packages présents dans node_modules/@types. Désormais, la valeur par défaut est un tableau vide. Cette modification peut améliorer les temps de build de 20 à 50 % sur certains projets, mais nécessite de déclarer explicitement les types nécessaires :
{
"compilerOptions": {
"types": ["node", "jest"]
}
}Si vous voyez des erreurs du type « Cannot find module '...' or its corresponding type declarations », c'est très probablement lié à ce changement.
Dépréciations majeures
TypeScript 6.0 déprécie un nombre conséquent d'options historiques. Ces dépréciations peuvent être temporairement ignorées en ajoutant "ignoreDeprecations": "6.0" dans votre tsconfig, mais TypeScript 7.0 ne supportera aucune de ces options.
target: es5
ES5 est déprécié. ECMAScript 2015 a été publié il y a plus de dix ans, Internet Explorer est retiré, et tous les navigateurs modernes sont evergreen. La cible minimale est désormais ES2015. Si vous avez encore besoin de sortie ES5, utilisez un compilateur externe comme esbuild, Babel ou SWC en post-traitement.
--downlevelIteration
Cette option n'avait d'effet que sur l'émission ES5. Avec la dépréciation de cette cible, elle n'a plus de raison d'être.
--moduleResolution node (alias node10)
Cette stratégie de résolution reflétait le comportement de Node.js 10 et ignorait toutes les évolutions ultérieures. Les projets doivent migrer vers nodenext (pour Node.js) ou bundler (pour les bundlers et Bun).
Valeurs amd, umd, systemjs et none pour --module
Ces systèmes de modules étaient importants à l'ère pré-ESM. Aujourd'hui, ESM est universellement supporté et ces options n'ont plus lieu d'être.
--baseUrl
Cette option était principalement utilisée comme préfixe pour les entrées paths, mais elle servait aussi involontairement de racine de résolution pour les modules, causant des résolutions incorrectes. Les développeurs doivent retirer baseUrl et ajouter les préfixes directement dans leurs entrées paths :
{
"compilerOptions": {
"paths": {
"@app/*": ["./src/app/*"],
"@lib/*": ["./src/lib/*"]
}
}
}--moduleResolution classic
L'algorithme de résolution historique de TypeScript, antérieur à celui de Node.js, est supprimé. Migration vers nodenext ou bundler requise.
--esModuleInterop false et --allowSyntheticDefaultImports false
Le comportement d'interopérabilité sûr entre ESM et CommonJS est désormais toujours activé. Certains imports devront être ajustés :
// Ancien style (esModuleInterop: false)
import * as express from "express";
// Nouveau style (toujours actif)
import express from "express";--alwaysStrict false
Tout le code est désormais considéré comme étant en mode strict JavaScript. Si vous avez du code « sloppy mode » utilisant des mots réservés comme identifiants (await, static, private, public), il faudra les renommer.
--outFile
Cette option de concaténation de fichiers est supprimée. Les bundlers modernes (Webpack, Rollup, esbuild, Vite, Parcel) font ce travail de manière bien plus performante et configurable.
Syntaxe module pour les namespaces
L'ancienne syntaxe module Foo { ... } pour déclarer des namespaces est désormais une erreur. Utilisez namespace Foo { ... } à la place. La forme declare module "..." pour les déclarations ambiantes reste parfaitement supportée.
Mot-clé asserts sur les imports
La syntaxe import ... asserts { type: "json" } est remplacée par import ... with { type: "json" }, conformément à l'évolution de la proposition ECMAScript d'import assertions vers import attributes.
Directive no-default-lib
La directive /// <reference no-default-lib="true"/> n'est plus supportée. Utilisez --noLib ou --libReplacement à la place.
Autre changement notable
Fichiers en ligne de commande avec tsconfig.json
Exécuter tsc foo.ts dans un dossier contenant un tsconfig.json produira désormais une erreur explicite, au lieu d'ignorer silencieusement la configuration. Utilisez le nouveau flag --ignoreConfig si vous souhaitez volontairement ignorer le tsconfig.
Préparer la migration vers TypeScript 7.0
L'équipe TypeScript est catégorique : TypeScript 7.0 est extrêmement proche de sa complétion. Une release est attendue dans les prochains mois, et de larges codebases internes et externes à Microsoft l'utilisent déjà.
La stratégie de migration recommandée est la suivante :
- Adopter TypeScript 6.0 et résoudre toutes les dépréciations sans utiliser
ignoreDeprecations. - Tester le flag
--stableTypeOrderingpour identifier les différences d'ordonnancement de types entre 6.0 et 7.0. - Essayer les previews natives de TypeScript 7.0 disponibles sur npm et via l'extension VS Code.
- Utiliser l'outil expérimental ts5to6 pour automatiser certains ajustements de configuration (
baseUrl,rootDir).
En résumé
TypeScript 6.0 est une version de transition ambitieuse qui fait le ménage dans plus d'une décennie d'options historiques tout en introduisant des fonctionnalités modernes. Les dépréciations sont nombreuses mais reflètent l'évolution profonde de l'écosystème JavaScript : ESM est partout, les navigateurs sont evergreen, et les bundlers ont rendu obsolètes de nombreux mécanismes intégrés au compilateur.
Si les changements de valeurs par défaut (strict: true, types: [], rootDir: ".") risquent de demander un peu de travail sur les projets existants, ils représentent des choix sensés qui améliorent les performances et la prévisibilité. Et surtout, cette version prépare le terrain pour TypeScript 7.0 et son compilateur Go, qui promet des gains de performance spectaculaires grâce au parallélisme natif.
Le message est clair : c'est le moment de moderniser vos configurations TypeScript. Le futur arrive vite.