- Dernière release de l’actuelle base de code JavaScript et release de transition préparant le passage à TypeScript 7.0, le port natif écrit en Go
- Améliorations de l’inférence de types et de la résolution de modules, dont un assouplissement de la sensibilité au contexte pour les fonctions qui n’utilisent pas
this, ainsi que la prise en charge des subpath imports commençant par #/
- Modernisation majeure des valeurs par défaut des options du compilateur :
strict passe à true, target à es2025, types à [], etc.
- Dépréciation massive d’options legacy comme la cible ES5, les modules AMD/UMD/SystemJS,
--baseUrl, --moduleResolution node10, etc.
- Ajout de la prise en charge des types pour les propositions ECMAScript Stage 4 les plus récentes, comme l’API Temporal,
getOrInsert/getOrInsertComputed de Map, ou encore RegExp.escape
Positionnement de TypeScript 6.0
- Dernière release basée sur l’actuelle base de code JavaScript, elle sert de pont vers TypeScript 7.0 (port natif en Go)
- TypeScript 7.0 exploite le code natif et le multithreading à mémoire partagée, et il est déjà tout proche d’être finalisé
- La plupart des changements de la 6.0 visent à aligner et préparer l’adoption de la 7.0
- TypeScript 7.0 peut déjà être testé via l’extension VS Code ou le package npm
Changements depuis la Beta et la RC
- Ajustement du type checking des expressions de fonction dans les appels génériques (en particulier les expressions JSX génériques) — cela permet de détecter davantage de bugs dans le code existant, mais certains appels génériques peuvent désormais nécessiter des arguments de type explicites
- Extension de la dépréciation de la syntaxe d’import assertion (
assert) aux appels import()
- Mise à jour des types DOM — prise en compte des standards Web les plus récents, avec des ajustements liés à l’API Temporal
Assouplissement de la sensibilité au contexte pour les fonctions qui n’utilisent pas this
- Lors de l’inférence des types, TypeScript classe les fonctions ayant des paramètres sans type explicite comme des fonctions contextuellement sensibles (contextually sensitive function) et leur donne une priorité plus basse dans l’ordre d’inférence
- Les fonctions écrites avec une syntaxe de méthode avaient toujours un paramètre implicite
this, et étaient donc toujours considérées comme contextuellement sensibles, contrairement aux fonctions fléchées
- Cela pouvait faire échouer l’inférence de types selon l’ordre des méthodes dans un littéral objet
- Dans TypeScript 6.0, les fonctions qui n’utilisent pas réellement
this ne sont plus considérées comme contextuellement sensibles
- Leur priorité augmente dans l’inférence de types, ce qui permet une inférence correcte quel que soit l’ordre des méthodes
- Implémenté grâce à une contribution de Mateusz Burzyński
Prise en charge des Subpath Imports commençant par #/
- La fonctionnalité subpath imports de Node.js permet de définir des alias vers des modules internes d’un package via le champ
imports du package.json
- Jusqu’ici, un caractère était obligatoire après
#, ce qui empêchait l’utilisation de chemins commençant par #/
- Cela créait de la confusion pour les développeurs habitués à la convention de préfixe
@/ dans les bundlers
- Node.js a récemment commencé à prendre en charge les subpath imports commençant par
#/
- Cela permet des mappings plus concis de la forme
"#/*": "./dist/*"
- TypeScript 6.0 les prend en charge avec les options
--moduleResolution nodenext et bundler
- Implémenté grâce à une contribution de magic-akari
Autorisation de la combinaison --moduleResolution bundler et --module commonjs
- Jusqu’ici,
--moduleResolution bundler ne pouvait être utilisé qu’avec --module esnext ou --module preserve
- Avec la dépréciation de
--moduleResolution node (node10), cette nouvelle combinaison constitue le chemin de mise à niveau le plus adapté pour de nombreux projets
- À long terme, il est recommandé de migrer vers
--module preserve + --moduleResolution bundler ou vers --module nodenext
Flag --stableTypeOrdering
- En interne, les ID de type attribués par TypeScript dépendent de l’ordre de traitement, et servent ensuite à trier les types union
- Cela pouvait entraîner des comportements imprévisibles où le résultat de l’emit des déclarations variait selon l’ordre des déclarations
- TypeScript 7.0 introduisant le type checking parallèle, il utilise un algorithme de tri déterministe basé sur le contenu pour résoudre les problèmes d’attribution d’ID non déterministes
- Exemple :
100 | 500 sera toujours émis dans le même ordre
- Activer
--stableTypeOrdering dans la 6.0 permet d’aligner le comportement de tri des types sur celui de la 7.0 et de réduire les écarts entre les deux bases de code
- Cela peut provoquer jusqu’à 25 % de baisse de performances lors du type checking
- En cas d’erreurs de types dues à des différences d’inférence, il est possible de corriger en ajoutant des arguments de type explicites ou des annotations de variables
- Ce flag est prévu uniquement pour diagnostiquer la migration de la 6.0 vers la 7.0 et son usage prolongé est déconseillé
Option es2025 (target et lib)
- ES2025 n’introduit pas de nouvelles fonctionnalités du langage JavaScript, mais ajoute des types d’API intégrées (par exemple
RegExp.escape)
- Des éléments auparavant dans
esnext, comme Promise.try, les méthodes de Iterator et celles de Set, sont déplacés vers es2025
- Implémenté grâce à une contribution de Kenta Moriuchi
Prise en charge des types pour l’API Temporal
- Les types intégrés de la proposition Temporal, désormais au Stage 4, sont inclus dans TypeScript 6.0
- Disponibles avec
--target esnext ou "lib": ["esnext"] (ou plus finement esnext.temporal)
- Les API comme
Temporal.Now.instant().subtract() ou .add() peuvent être utilisées avec une sécurité de typage
- Déjà disponible dans plusieurs runtimes, Temporal fait désormais officiellement partie du langage JavaScript grâce à son passage au Stage 4
- Implémenté grâce à une contribution de Renegade334
Prise en charge des types pour les méthodes d’"upsert" de Map (getOrInsert / getOrInsertComputed)
- Cela simplifie le motif répétitif consistant à vérifier si une clé existe dans une
Map et, sinon, à y définir une valeur par défaut
- La proposition ECMAScript d’"upsert" est passée au Stage 4, ajoutant deux nouvelles méthodes à
Map et WeakMap
getOrInsert : insère puis renvoie la valeur par défaut spécifiée si la clé est absente
getOrInsertComputed : calcule la valeur par défaut à la demande via un callback lorsque son coût de création est élevé
- Le callback reçoit la clé en argument, ce qui permet aussi de générer une valeur par défaut dépendant de la clé
- Ajoutées à la lib
esnext, elles sont immédiatement utilisables dans TypeScript 6.0
- Implémenté grâce à une contribution de Renegade334
RegExp.escape
- La fonction
RegExp.escape, qui échappe les caractères spéciaux dans les expressions régulières, est passée au Stage 4
- Elle est incluse dans la lib
es2025 et peut être utilisée dans TypeScript 6.0
- Implémenté grâce à une contribution de Kenta Moriuchi
Intégration de dom.iterable et dom.asynciterable dans la lib dom
- Jusqu’ici, pour utiliser l’itération sur
NodeList, HTMLCollection, etc., il fallait préciser "lib": ["dom", "dom.iterable"]
- Dans TypeScript 6.0, le contenu de
lib.dom.iterable.d.ts et lib.dom.asynciterable.d.ts est entièrement intégré dans lib.dom.d.ts
dom.iterable et dom.asynciterable restent référencables, mais sont désormais des fichiers vides
- Tous les principaux navigateurs modernes prenant déjà en charge ces fonctionnalités, il s’agit d’une amélioration de confort qui supprime une source fréquente de confusion
Principaux changements de valeurs par défaut
strict vaut désormais true par défaut : comme la plupart des nouveaux projets veulent le mode strict, les projets qui dépendaient de false doivent maintenant définir explicitement "strict": false
module vaut désormais esnext par défaut : cela reflète la domination d’ESM comme format de module
target pointe par défaut vers la dernière version d’ES (actuellement es2025) : avec la généralisation des runtimes evergreen, le transpile vers d’anciennes versions devient inutile
noUncheckedSideEffectImports vaut désormais true par défaut : cela aide à détecter les fautes de frappe dans les imports uniquement destinés aux effets de bord
libReplacement vaut désormais false par défaut : cela améliore les performances par défaut en évitant des échecs inutiles de résolution de modules et davantage de fichiers surveillés
rootDir passe à . par défaut
- Jusqu’ici, quand il n’était pas précisé, il était déterminé en inférant le répertoire commun à tous les fichiers d’entrée non déclaratifs
- Cela impliquait de charger et parser le projet pour déterminer si un fichier en faisait partie
- Dans TypeScript 6.0, la valeur par défaut devient le répertoire contenant
tsconfig.json
- Si les fichiers sources se trouvent plus profondément que
tsconfig.json, il faut définir explicitement "rootDir": "./src", par exemple
- Sinon, on peut obtenir une structure de sortie non souhaitée comme
./dist/src/index.js
types passe à [] par défaut
- Jusqu’ici, tous les packages présents dans
node_modules/@types étaient inclus automatiquement, ce qui ajoutait un important surcoût au temps de build
- Dans un dépôt classique, il est fréquent que des centaines de packages
@types soient inclus transitivement
- Dans TypeScript 6.0, la valeur par défaut devient
[] (tableau vide), ce qui évite de charger des fichiers de déclarations inutiles
- Des cas concrets montrent des améliorations du temps de build de 20 à 50 %
- La plupart des projets devront définir explicitement
"types": ["node"] ou "types": ["node", "jest"], par exemple
- Il est possible de restaurer l’ancien comportement avec
"types": ["*"]
Éléments dépréciés (Deprecation)
Dépréciation de target: es5
- La cible ES5 n’a presque plus de cas d’usage depuis la disparition d’IE et la généralisation des navigateurs evergreen
- La cible minimale passe à ES2015 ; si une sortie ES5 est nécessaire, il est recommandé d’utiliser un compilateur externe
Dépréciation de --downlevelIteration
- Cette option n’avait d’effet qu’avec l’emit ES5 ; avec la dépréciation de la cible ES5, elle perd donc sa raison d’être
Dépréciation de --moduleResolution node (node10)
- Elle reflétait l’algorithme de résolution de modules de Node.js 10, désormais en décalage avec le comportement des versions modernes de Node.js
- Il est recommandé de migrer vers
nodenext (ciblage direct de Node.js) ou bundler (bundlers/Bun)
Dépréciation des valeurs de module AMD, UMD et SystemJS
--module amd, --module umd, --module systemjs et --module none ne sont plus pris en charge
- ESM étant désormais largement pris en charge dans les navigateurs comme dans Node.js, il faut migrer vers un bundler ou vers une cible ESM
Dépréciation de --baseUrl
- Il était surtout utilisé comme préfixe pour
paths, mais agissait aussi comme racine de lookup pour la résolution de modules, ce qui pouvait provoquer des résolutions de chemins inattendues
- La migration consiste à supprimer
baseUrl et à ajouter directement le préfixe dans les entrées paths
- Exemple :
"@app/*": ["app/*"] → "@app/*": ["./src/app/*"]
Dépréciation de --moduleResolution classic
- Il s’agit de l’algorithme de résolution de modules d’origine de TypeScript, mais tous les cas pratiques actuels peuvent être remplacés par
nodenext ou bundler
Dépréciation de esModuleInterop false et allowSyntheticDefaultImports false
- Il devient impossible de mettre ces deux options à
false, ce qui signifie que le comportement d’interop sûr est toujours activé
- Il peut donc être nécessaire d’ajuster
import * as express from "express" en import express from "express"
Dépréciation de --alwaysStrict false
- Tout le code est désormais considéré en mode strict JavaScript, ce qui impose de renommer les identifiants comme
await, static ou private lorsqu’ils étaient utilisés comme noms ordinaires
Dépréciation de outFile
- Cette fonctionnalité permettait de fusionner plusieurs fichiers d’entrée en un seul, mais elle est désormais remplacée par des bundlers externes comme Webpack, Rollup, esbuild ou Vite
- La décision vise à recentrer TypeScript sur son rôle principal : le type checking et l’emit des déclarations
Dépréciation de l’ancienne syntaxe module (déclarations de namespace)
- La syntaxe
module Foo { ... } est dépréciée de manière stricte et doit être remplacée par namespace Foo { ... }
- Les déclarations de modules ambient sous la forme
declare module "some-module" { ... } restent prises en charge
- L’objectif est d’éviter les conflits avec la proposition ECMAScript des blocs
module
Dépréciation du mot-clé d’import asserts
- Il faut remplacer
import ... asserts { type: "json" } par import ... with { type: "json" }
- Cette évolution suit le remplacement de la proposition d’import assertions par la proposition d’import attributes (mot-clé
with)
Dépréciation de la directive no-default-lib
/// <reference no-default-lib="true"/> n’est plus pris en charge ; il est recommandé d’utiliser --noLib ou --libReplacement
Erreur lors de la spécification de fichiers en ligne de commande si tsconfig.json existe
- En exécutant
tsc foo.ts, une erreur est générée si un tsconfig.json est présent dans le même répertoire
- Il est possible de l’ignorer explicitement avec le flag
--ignoreConfig
Préparer TypeScript 7.0
- Les options dépréciées en 6.0 peuvent encore être utilisées sans erreur via le paramètre
"ignoreDeprecations": "6.0", mais elles seront entièrement supprimées dans la 7.0
- L’outil ts5to6 permet d’ajuster automatiquement
baseUrl, rootDir, etc.
- TypeScript 7.0 devrait sortir dans les prochains mois et il est déjà largement adopté dans de très grosses bases de code, chez Microsoft comme à l’extérieur
- Les retours sont encouragés via les builds nightly de la preview native et l’extension VS Code
Aucun commentaire pour le moment.