IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

TypeScript Discussion :

Microsoft annonce la version stable de TypeScript 6.0


Sujet :

TypeScript

  1. #1
    Communiqués de presse

    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Avril 2025
    Messages
    591
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : Avril 2025
    Messages : 591
    Par défaut Microsoft annonce la version stable de TypeScript 6.0
    Microsoft annonce la version Beta de TypeScript 6.0 apportant des améliorations aux fonctions sensibles au contexte ainsi que la prise en charge des importations de sous-chemins

    Microsoft annonce la version Beta de TypeScript 6.0. Voici quelques-uns des points forts de cette version : moins de sensibilité au contexte pour les fonctions sans this, importations de sous-chemins commençant par #/, combinaison de --moduleResolution bundler avec --module commonjs, le drapeau --stableTypeOrdering, l'option es2025 pour target et lib, entre autres. TypeScript 6.0 est une version unique en son genre, car son équipe a l'intention d'en faire la dernière version basée sur le code source JavaScript actuel. Comme annoncé en 2025, ils travaillent sur un nouveau code source pour le compilateur TypeScript et le service linguistique écrit en Go qui tire parti de la vitesse du code natif et du multithreading à mémoire partagée.

    TypeScript est un langage qui s'appuie sur JavaScript en ajoutant une syntaxe pour les types. L'écriture de types dans le code permet d'expliquer l'intention et de faire vérifier le code par d'autres outils pour détecter les erreurs comme les fautes de frappe, les problèmes avec null et undefined, et plus encore. Les types alimentent également les outils d'édition de TypeScript, comme l'auto-complétion, la navigation dans le code et les refactorisations que vous pouvez voir dans des éditeurs tels que Visual Studio et VS Code. En fait, TypeScript et son écosystème alimentent l'expérience JavaScript dans ces deux éditeurs également.

    TypeScript 6.0 est une version unique en son genre, car son équipe a l'intention d'en faire la dernière version basée sur le code source JavaScript actuel. Comme annoncé en 2025, ils travaillent sur un nouveau code source pour le compilateur TypeScript et le service linguistique écrit en Go qui tire parti de la vitesse du code natif et du multithreading à mémoire partagée. Cette nouvelle base de code constituera le fondement de TypeScript 7.0 et des versions ultérieures. TypeScript 6.0 sera le précurseur immédiat de cette version et, à bien des égards, il servira de pont entre TypeScript 5.9 et 7.0. À ce titre, la plupart des changements apportés à TypeScript 6.0 visent à faciliter l'alignement et la préparation à l'adoption de TypeScript 7.0.

    Nom : 1.jpg
Affichages : 10614
Taille : 10,6 Ko

    Voici quelques-uns des points forts de cette version, avec des détails sur ce qui va changer dans la version 7.0 :

    Moins de sensibilité au contexte pour les fonctions sans this

    Lorsque les paramètres n'ont pas de types explicites, TypeScript peut généralement les déduire en fonction d'un type attendu, ou même à partir d'autres arguments dans le même appel de fonction.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works, no issues.
    callIt({
        produce: (x: number) => x * 2,
        consume: y => y.toFixed(),
    });
     
    // Works, no issues even though the order of the properties is flipped.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });



    Ici, TypeScript peut déduire le type de y dans la fonction consume en se basant sur le type T déduit de la fonction produce, quel que soit l'ordre des propriétés. Mais qu'en est-il si ces fonctions ont été écrites en utilisant la syntaxe de méthode plutôt que la syntaxe de fonction fléchée ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works fine, `x` is inferred to be a number.
    callIt({
        produce(x: number) { return x * 2; },
        consume(y) { return y.toFixed(); },
    });
     
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Curieusement, le deuxième appel à callIt génère une erreur, car TypeScript n'est pas en mesure de déduire le type de y dans la méthode consume. Ce qui se passe ici, c'est que lorsque TypeScript essaie de trouver des candidats pour T, il ignore d'abord les fonctions dont les paramètres n'ont pas de types explicites. Il procède ainsi parce que certaines fonctions peuvent avoir besoin que le type déduit de T soit correctement vérifié. Dans ce cas, on a besoin de connaître le type de T pour analyser la fonction consume.

    Ces fonctions sont appelées fonctions sensibles au contexte, c'est-à-dire des fonctions dont les paramètres n'ont pas de types explicites. Au final, le système de types devra déterminer les types de ces paramètres, mais cela va à l'encontre du fonctionnement de l'inférence dans les fonctions génériques, car les deux « tirent » les types dans des directions différentes.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function callFunc<T>(callback: (x: T) => void, value: T) {
        return callback(value);
    }
     
    callFunc(x => x.toFixed(), 42);
    //       ^
    // We need to figure out the type of `x` here,
    // but we also need to figure out the type of `T` to check the callback.



    Pour résoudre ce problème, TypeScript ignore les fonctions sensibles au contexte lors de l'inférence des arguments de type et vérifie et infère d'abord à partir d'autres arguments. Si le fait d'ignorer les fonctions sensibles au contexte ne fonctionne pas, l'inférence se poursuit simplement sur tous les arguments non vérifiés, en allant de gauche à droite dans la liste des arguments. Dans l'exemple ci-dessus, TypeScript ignorera le rappel lors de l'inférence pour T, mais examinera ensuite le deuxième argument, 42, et en déduira que T est un nombre. Ensuite, lorsqu'il reviendra vérifier le rappel, il aura un type contextuel de (x: nombre) => void, ce qui lui permettra de déduire que x est également un nombre.

    Que se passe-t-il donc dans nos exemples précédents ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Arrow syntax - no errors.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });
     
    // Method syntax - errors!
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Dans les deux exemples, une fonction avec un paramètre x explicitement typé est attribuée à produce. Ne devraient-ils pas être vérifiés de manière identique ?

    La question est subtile : la plupart des fonctions (comme celles qui utilisent la syntaxe de méthode) ont un paramètre this implicite, mais ce n'est pas le cas des fonctions fléchées. Toute utilisation de this pourrait nécessiter de « tirer » sur le type de T. Par exemple, connaître le type de l'objet littéral contenant pourrait à son tour nécessiter le type de consume, qui utilise T.

    Mais nous n'utilisons pas this ! Bien sûr, la fonction peut avoir une valeur this lors de l'exécution, mais elle n'est jamais utilisée !

    TypeScript 6.0 en tient compte lorsqu'il décide si une fonction est sensible au contexte ou non. Si this n'est jamais réellement utilisé dans une fonction, alors il n'est pas considéré comme sensible au contexte. Cela signifie que ces fonctions seront considérées comme ayant une priorité plus élevée en matière d'inférence de type, et tous nos exemples ci-dessus fonctionnent désormais !

    Importations de sous-chemins commençant par #/

    Lorsque Node.js a ajouté la prise en charge des modules, il a ajouté une fonctionnalité appelée « importations de sous-chemins ». Il s'agit essentiellement d'un champ appelé imports qui permet aux paquets de créer des alias internes pour les modules au sein de leur paquet.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#root": "./dist/index.js",
            "#root/*": "./dist/*"
        }
    }



    Cela permet aux modules de my-package d'importer à partir de #root au lieu d'avoir à utiliser un chemin relatif comme ../../index.js, et permet essentiellement à tout autre module d'écrire quelque chose comme

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "#root/utils.js";



    au lieu d'utiliser un chemin relatif comme celui-ci.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "../../utils.js";



    Un inconvénient mineur de cette fonctionnalité est que les développeurs devaient toujours écrire quelque chose après le # lorsqu'ils spécifiaient une importation de sous-chemin. Ici, on utilise root, mais cela est un peu inutile puisqu'il n'y a pas d'autre répertoire que ./dist/ sur lequel nous effectuons le mappage.

    Les développeurs qui ont utilisé des bundlers sont également habitués à utiliser le mappage de chemins pour éviter les longs chemins relatifs. Une convention courante avec les bundlers consiste à utiliser un simple @/ comme préfixe. Malheureusement, les importations de sous-chemins ne pouvaient pas commencer par #/, ce qui causait beaucoup de confusion pour les développeurs qui essayaient de les adopter dans leurs projets.

    Mais plus récemment, Node.js a ajouté la prise en charge des importations de sous-chemins commençant par #/. Cela permet aux paquets d'utiliser un simple préfixe #/ pour leurs importations de sous-chemins sans avoir à ajouter de segment supplémentaire.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#": "./dist/index.js",
            "#/*": "./dist/*"
        }
    }



    Cette fonctionnalité est prise en charge dans les nouvelles versions de Node.js 20. TypeScript la prend donc désormais en charge dans les options node20, nodenext et bundler pour le paramètre --moduleResolution.

    Combinaison de --moduleResolution bundler avec --module commonjs

    Le paramètre --moduleResolution bundler de TypeScript ne pouvait auparavant être utilisé qu'avec --module esnext ou --module preserve ; cependant, avec la dépréciation du nœud --moduleResolution (alias --moduleResolution node10), cette nouvelle combinaison est souvent la voie de mise à niveau la plus appropriée pour de nombreux projets.

    Les projets voudront souvent planifier une migration vers l'un des deux éléments suivants

    - --module preserve et --moduleResolution bundler.
    - --module nodenext.

    en fonction du type de projet (par exemple, application web groupée, application Bun ou application Node.js).

    Le drapeau --stableTypeOrdering

    Dans le cadre du travail continu sur le portage natif de TypeScript, l'équipe de typeScprit a introduit un nouveau drapeau appelé --stableTypeOrdering destiné à faciliter les migrations de la version 6.0 à la version 7.0.

    Aujourd'hui, TypeScript attribue des identifiants de type (numéros de suivi internes) aux types dans l'ordre où ils apparaissent, et utilise ces identifiants pour trier les types d'union de manière cohérente. Un processus similaire s'applique aux propriétés. Par conséquent, l'ordre dans lequel les éléments sont déclarés dans un programme peut avoir des effets surprenants sur des éléments tels que l'émission de déclarations.

    Prenons par exemple l'émission de déclarations à partir de ce fichier :

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Input: some-file.ts
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 100 | 500;
    //                                               ^^^^^^^^^
    //             Note the order of this union: 100, then 500.



    Si nous ajoutons une constante non liée au-dessus de foo, la déclaration émise change :

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Input: some-file.ts
    const x = 500;
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 500 | 100;
    //                                               ^^^^^^^^^
    //                           Note the change in order here.



    Cela se produit parce que le type littéral 500 obtient un ID de type inférieur à 100, car il a été traité en premier lors de l'analyse de la déclaration de la const x. Dans de très rares cas, ce changement d'ordre peut même entraîner l'apparition ou la disparition d'erreurs en fonction de l'ordre de traitement du programme, mais en général, c'est principalement dans les fichiers de déclaration émis ou dans la façon dont les types sont affichés dans votre éditeur que vous remarquerez cet ordre.

    L'une des principales améliorations architecturales de TypeScript 7 est la vérification parallèle des types, qui réduit considérablement le temps de vérification global. Cependant, le parallélisme pose un défi : lorsque différents vérificateurs de types visitent les nœuds, les types et les symboles dans des ordres différents, les identifiants internes attribués à ces constructions deviennent non déterministes. Cela conduit à des résultats non déterministes prêtant à confusion, où deux fichiers au contenu identique dans le même programme peuvent produire des fichiers de déclaration différents, voire calculer des erreurs différentes lors de l'analyse du même fichier. Pour remédier à cela, TypeScript 7.0 trie ses objets internes (par exemple, les types et les symboles) selon un algorithme déterministe basé sur le contenu de l'objet. Cela garantit que tous les vérificateurs rencontrent le même ordre d'objets, indépendamment de la manière et du moment où ils ont été créés. En conséquence, dans l'exemple donné, TypeScript 7 affichera toujours 100 | 500, supprimant ainsi complètement l'instabilité de l'ordre.

    Cela signifie que TypeScript 6 et 7 peuvent parfois afficher un ordre différent. Bien que ces changements d'ordre soient presque toujours bénins, si vous comparez les résultats du compilateur entre deux exécutions (par exemple, en vérifiant les fichiers de déclaration émis dans 6.0 par rapport à 7.0), ces différents ordres peuvent produire beaucoup de bruit, ce qui rend difficile l'évaluation de l'exactitude. Parfois, cependant, vous pouvez constater un changement dans l'ordre qui provoque l'apparition ou la disparition d'une erreur de type, ce qui peut être encore plus déroutant.

    Pour remédier à cette situation, dans la version 6.0, vous pouvez spécifier le nouveau drapeau --stableTypeOrdering. Cela permet d'aligner le comportement de classement des types de la version 6.0 sur celui de la version 7.0, réduisant ainsi le nombre de différences entre les deux bases de code. Notez qu'il n'est pas nécessairement recommandé d'utiliser ce drapeau en permanence, car il peut ralentir considérablement la vérification des types (jusqu'à 25 % selon la base de code).

    Si vous rencontrez une erreur de type en utilisant [c]--stableTypeOrdering[c], cela est généralement dû à des différences d'inférence. L'inférence précédente sans --stableTypeOrdering fonctionnait sur la base de l'ordre actuel des types dans votre programme. Pour remédier à cela, il est souvent utile de fournir un type explicite quelque part. Il s'agira souvent d'un argument de type

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    - someFunctionCall(/*...*/);
    + someFunctionCall<SomeExplicitType>(/*...*/);



    ou d'une annotation de variable pour un argument que vous avez l'intention de passer dans un appel.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    - const someVariable = { /*... some complex object ...*/ };
    + const someVariable: SomeExplicitType = { /*... some complex object ...*/ };
     
    someFunctionCall(someVariable);



    Notez que cet indicateur est uniquement destiné à aider à diagnostiquer les différences entre les versions 6.0 et 7.0. Il n'est pas destiné à être utilisé comme fonctionnalité à long terme.

    Option es2025 pour target et lib

    TypeScript 6.0 ajoute la prise en charge de l'option es2025 pour target et lib. Bien qu'il n'y ait pas de nouvelles fonctionnalités du langage JavaScript dans ES2025, cette nouvelle cible ajoute de nouveaux types pour les API intégrées (par exemple RegExp.escape) et déplace quelques déclarations de esnext vers es2025 (par exemple Promise.try, les méthodes Iterator et les méthodes Set).

    Nouveaux types pour Temporal

    La proposition Temporal tant attendue a atteint la phase 3 et devrait être ajoutée à JavaScript dans un avenir proche. TypeScript 6.0 inclut désormais des types intégrés pour l'API Temporal, vous pouvez donc commencer à l'utiliser dès aujourd'hui dans votre code TypeScript via --target esnext ou "lib" : ["esnext"] (ou le plus granulaire temporal.esnext).

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let yesterday = Temporal.Now.instant().subtract({
        hours: 24,
    });
     
    let tomorrow = Temporal.Now.instant().add({
        hours: 24,
    });
     
    console.log(`Yesterday: ${yesterday}`);
    console.log(`Tomorrow: ${tomorrow}`);



    Temporal est déjà utilisable dans plusieurs environnements d'exécution, vous devriez donc pouvoir commencer à l'expérimenter rapidement.

    Préparation pour TypeScript 7.0

    TypeScript 6.0 est conçu comme une version de transition. Bien que les options obsolètes dans TypeScript 6.0 continueront de fonctionner sans erreur lorsque "ignoreDeprecations" : "6.0" est défini, elles seront entièrement supprimées dans TypeScript 7.0 (le port TypeScript natif). Si vous voyez des avertissements de dépréciation après la mise à niveau vers TypeScript 6.0, il est vivement recommandé de les traiter avant d'essayer d'adopter TypeScript 7 (ou ses aperçus natifs) dans votre projet.

    En ce qui concerne le calendrier entre TypeScript 6.0 et 7.0, l'équipe prévoit de publier la version 7.0 peu après la version 6.0. Cela devrait aider à maintenir une certaine continuité dans le développement et permettre de résoudre les problèmes plus rapidement après la publication de la version 7.0.

    À ce stade, TypeScript 6.0 est « stable en termes de fonctionnalités » et il n'est pas prévu d'ajouter de nouvelles fonctionnalités ni d'apporter de modifications importantes. Au cours des prochaines semaines, ils traiteront tous les nouveaux problèmes signalés dans le code source 6.0. Ils continuent également à travailler sur TypeScript 7.0 et publiront des versions nocturnes des aperçus natifs ainsi qu'une extension VS Code.

    Source : Annonce de TypeScript 6.0 Beta

    Et vous ?

    Pensez-vous que cette annonce est crédible ou pertinente ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    Microsoft annonce la version candidate (RC) de TypeScript 5.9 apportant des mise à jour à tsc --init ainsi que la prise en charge de import defer et de --module node20

    Un TypeScript 10x plus rapide : Anders Hejlsberg, architecte principal de Microsoft pour TypeScript, présente un nouveau portage de TypeScript qui offrira aux développeurs un outil de haute performance

    Pourquoi je suis sceptique quant à la réécriture des outils JavaScript dans des langages "plus rapides", par Nolan Lawson
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  2. #2
    Communiqués de presse

    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Avril 2025
    Messages
    591
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : Avril 2025
    Messages : 591
    Par défaut Microsoft annonce la version Release Candidate de TypeScript 6.0
    Microsoft annonce la version Release Candidate de TypeScript 6.0 apportant des améliorations à la vérification des types pour les expressions de fonction dans les appels génériques

    Microsoft annonce la sortie de la version Release Candidate (RC) de TypeScript 6.0. Depuis la version bêta de TypeScript 6.0, cette version apporte quelques modifications notables, principalement pour aligner le comportement sur celui de TypeScript 7.0. L'une des modifications concerne la vérification des types pour les expressions de fonction dans les appels génériques, en particulier celles qui apparaissent dans les expressions JSX génériques. Cela permettra généralement de détecter davantage de bogues dans le code existant, mais vous constaterez peut-être que certains appels génériques nécessitent un argument de type explicite.

    TypeScript est un langage qui s'appuie sur JavaScript en ajoutant une syntaxe pour les types. L'écriture de types dans le code permet d'expliquer l'intention et de faire vérifier le code par d'autres outils pour détecter les erreurs comme les fautes de frappe, les problèmes avec null et undefined, et plus encore. Les types alimentent également les outils d'édition de TypeScript, comme l'auto-complétion, la navigation dans le code et les refactorisations que vous pouvez voir dans des éditeurs tels que Visual Studio et VS Code. En fait, TypeScript et son écosystème alimentent l'expérience JavaScript dans ces deux éditeurs également.

    Début février 2026, Microsoft a annoncé la version Beta de TypeScript 6.0. Récemment, Microsoft annonce la sortie de la version Release Candidate (RC) de TypeScript 6.0. Depuis la version bêta de TypeScript 6.0, cette version apporte quelques modifications notables, principalement pour aligner le comportement sur celui de TypeScript 7.0.

    TypeScript 6.0 est une version unique en son genre, car son équipe a l'intention d'en faire la dernière version basée sur le code source JavaScript actuel. Comme annoncé en 2025, ils travaillent sur un nouveau code source pour le compilateur TypeScript et le service linguistique écrit en Go qui tire parti de la vitesse du code natif et du multithreading à mémoire partagée. Cette nouvelle base de code constituera le fondement de TypeScript 7.0 et des versions ultérieures. TypeScript 6.0 sera le précurseur immédiat de cette version et, à bien des égards, il servira de pont entre TypeScript 5.9 et 7.0. À ce titre, la plupart des changements apportés à TypeScript 6.0 visent à faciliter l'alignement et la préparation à l'adoption de TypeScript 7.0.

    L'une des modifications concerne la vérification des types pour les expressions de fonction dans les appels génériques, en particulier celles qui apparaissent dans les expressions JSX génériques. Cela permettra généralement de détecter davantage de bogues dans le code existant, mais vous constaterez peut-être que certains appels génériques nécessitent un argument de type explicite. Ils ont également étendu la dépréciation de la syntaxe d'assertion d'importation (c'est-à-dire import ... assert {...}) aux appels import() tels que import(..., { assert: {...}}). Enfin, ils ont mis à jour les types DOM afin de refléter les dernières normes web, y compris certaines modifications apportées aux API temporelles.


    Moins de sensibilité au contexte pour les fonctions sans this

    Lorsque les paramètres n'ont pas de types explicites écrits, TypeScript peut généralement les déduire en fonction d'un type attendu, ou même à partir d'autres arguments dans le même appel de fonction.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works, no issues.
    callIt({
        produce: (x: number) => x * 2,
        consume: y => y.toFixed(),
    });
     
    // Works, no issues even though the order of the properties is flipped.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });



    Ici, TypeScript peut déduire le type de y dans la fonction consume en se basant sur le T déduit de la fonction produce, quel que soit l'ordre des propriétés. Mais qu'en est-il si ces fonctions étaient écrites en utilisant la syntaxe de méthode au lieu de la syntaxe de fonction fléchée ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works fine, `x` is inferred to be a number.
    callIt({
        produce(x: number) { return x * 2; },
        consume(y) { return y.toFixed(); },
    });
     
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Curieusement, le deuxième appel à callIt entraîne une erreur, car TypeScript n'est pas en mesure de déduire le type de y dans la méthode consume. Ce qui se passe ici, c'est que lorsque TypeScript essaie de trouver des candidats pour T, il ignore d'abord les fonctions dont les paramètres n'ont pas de types explicites. Il procède ainsi parce que certaines fonctions peuvent avoir besoin que le type déduit de T soit correctement vérifié. Dans notre cas, nous avons besoin de connaître le type de T pour analyser notre fonction consume.

    Ces fonctions sont appelées fonctions sensibles au contexte, c'est-à-dire des fonctions dont les paramètres n'ont pas de types explicites. Au final, le système de types devra déterminer les types de ces paramètres, mais cela va quelque peu à l'encontre du fonctionnement de la déduction dans les fonctions génériques, car les deux « tirent » les types dans des directions différentes.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function callFunc<T>(callback: (x: T) => void, value: T) {
        return callback(value);
    }
     
    callFunc(x => x.toFixed(), 42);
    //       ^
    // We need to figure out the type of `x` here,
    // but we also need to figure out the type of `T` to check the callback.



    Pour résoudre ce problème, TypeScript ignore les fonctions sensibles au contexte lors de l'inférence des arguments de type et vérifie et infère d'abord à partir d'autres arguments. Si le fait d'ignorer les fonctions sensibles au contexte ne fonctionne pas, l'inférence se poursuit simplement sur tous les arguments non vérifiés, en allant de gauche à droite dans la liste des arguments. Dans l'exemple ci-dessus, TypeScript ignorera le rappel lors de l'inférence pour T, mais examinera ensuite le deuxième argument, 42, et en déduira que T est un number. Ensuite, lorsqu'il reviendra vérifier le rappel, il aura un type contextuel de (x: nombre) => void, ce qui lui permettra de déduire que [c]x[/B] est également un number.

    Que se passe-t-il donc dans nos exemples précédents ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Arrow syntax - no errors.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });
     
    // Method syntax - errors!
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Dans les deux exemples, produce est assignée à une fonction avec un paramètre x explicitement typé. Ne devraient-ils pas être vérifiés de manière identique ?

    La question est subtile : la plupart des fonctions (comme celles qui utilisent la syntaxe de méthode) ont un paramètre this implicite, mais ce n'est pas le cas des fonctions fléchées. Toute utilisation de this pourrait nécessiter de « tirer » sur le type de T. Par exemple, connaître le type de l'objet littéral contenant pourrait à son tour nécessiter le type de consume, qui utilise T.

    Mais nous n'utilisons pas this ! Bien sûr, la fonction peut avoir une valeur this lors de l'exécution, mais elle n'est jamais utilisée !

    TypeScript 6.0 en tient compte lorsqu'il décide si une fonction est sensible au contexte ou non. Si this n'est jamais réellement utilisé dans une fonction, alors il n'est pas considéré comme sensible au contexte. Cela signifie que ces fonctions seront considérées comme ayant une priorité plus élevée en matière d'inférence de type, et tous nos exemples ci-dessus fonctionnent désormais !

    Importations de sous-chemins commençant par #/

    Lorsque Node.js a ajouté la prise en charge des modules, il a ajouté une fonctionnalité appelée « importations de sous-chemins ». Il s'agit essentiellement d'un champ appelé imports qui permet aux paquets de créer des alias internes pour les modules au sein de leur paquet.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#root": "./dist/index.js",
            "#root/*": "./dist/*"
        }
    }



    Cela permet aux modules de my-package d'importer à partir de #root au lieu d'avoir à utiliser un chemin relatif tel que ../../index.js, et permet essentiellement à tout autre module d'écrire quelque chose comme

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "#root/utils.js";



    au lieu d'utiliser un chemin relatif tel que celui ci-dessous.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "../../utils.js";



    Un inconvénient mineur de cette fonctionnalité est que les développeurs devaient toujours écrire quelque chose après le # lorsqu'ils spécifiaient une importation de sous-chemin. Ici, nous avons utilisé root, mais cela est un peu inutile puisqu'il n'y a pas d'autre répertoire que ./dist/Les développeurs qui ont utilisé des bundlers sont également habitués à utiliser le mappage de chemins pour éviter les longs chemins relatifs. Une convention courante avec les bundlers consiste à utiliser un simple @/ comme préfixe. Malheureusement, les importations de sous-chemins ne pouvaient pas commencer par #/, ce qui causait beaucoup de confusion pour les développeurs qui essayaient de les adopter dans leurs projets.

    Mais plus récemment, Node.js a ajouté la prise en charge des importations de sous-chemins commençant par #/. Cela permet aux paquets d'utiliser un simple préfixe #/ pour leurs importations de sous-chemins sans avoir à ajouter de segment supplémentaire.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#": "./dist/index.js",
            "#/*": "./dist/*"
        }
    }



    Cette fonctionnalité est prise en charge dans les nouvelles versions de Node.js 20. TypeScript la prend donc désormais en charge dans les options node20, nodenext et bundler pour le paramètre --moduleResolution.

    Combinaison de --moduleResolution bundler avec --module commonjs

    Le paramètre --moduleResolution bundler de TypeScript ne pouvait auparavant être utilisé qu'avec --module esnext ou --module preserve ; cependant, avec la dépréciation de --moduleResolution node (alias --moduleResolution node10), cette nouvelle combinaison est souvent la voie de mise à niveau la plus appropriée pour de nombreux projets.

    Les projets voudront souvent planifier une migration vers l'un des deux éléments suivants

    - --module preserve et --moduleResolution bundler,
    - --module nodenext,

    en fonction du type de projet (par exemple, application web groupée, application Bun ou application Node.js).

    Le drapeau --stableTypeOrdering

    Dans le cadre de notre travail continu sur le portage natif de TypeScript, cette version introduit un nouveau drapeau appelé --stableTypeOrdering destiné à faciliter les migrations de la version 6.0 à la version 7.0.

    Aujourd'hui, TypeScript attribue des identifiants de type (numéros de suivi internes) aux types dans l'ordre où ils apparaissent, et utilise ces identifiants pour trier les types d'union de manière cohérente. Un processus similaire s'applique aux propriétés. Par conséquent, l'ordre dans lequel les éléments sont déclarés dans un programme peut avoir des effets surprenants sur des éléments tels que l'émission de déclarations.

    Prenons par exemple l'émission de déclaration de ce fichier :

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Input: some-file.ts
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 100 | 500;
    //                                               ^^^^^^^^^
    //             Note the order of this union: 100, then 500.



    Si nous ajoutons const sans rapport au-dessus de foo, l'émission de déclaration change :

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Input: some-file.ts
    const x = 500;
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 500 | 100;
    //                                               ^^^^^^^^^
    //                           Note the change in order here.



    Cela se produit parce que le type littéral 500 obtient un identifiant de type inférieur à 100, car il a été traité en premier lors de l'analyse de la déclaration de la const x. Dans de très rares cas, ce changement d'ordre peut même entraîner l'apparition ou la disparition d'erreurs en fonction de l'ordre de traitement du programme, mais en général, c'est principalement dans les fichiers de déclaration émis ou dans la façon dont les types sont affichés dans votre éditeur que vous remarquerez cet ordre.

    L'une des principales améliorations architecturales de TypeScript 7 est la vérification parallèle des types, qui réduit considérablement le temps de vérification global. Cependant, le parallélisme pose un défi : lorsque différents vérificateurs de types visitent les nœuds, les types et les symboles dans des ordres différents, les identifiants internes attribués à ces constructions deviennent non déterministes. Cela conduit à des résultats non déterministes prêtant à confusion, où deux fichiers au contenu identique dans le même programme peuvent produire des fichiers de déclaration différents, voire calculer des erreurs différentes lors de l'analyse du même fichier. Pour remédier à cela, TypeScript 7.0 trie ses objets internes (par exemple, les types et les symboles) selon un algorithme déterministe basé sur le contenu de l'objet. Cela garantit que tous les vérificateurs rencontrent le même ordre d'objets, indépendamment de la manière et du moment où ils ont été créés. En conséquence, dans l'exemple donné, TypeScript 7 affichera toujours 100 | 500, supprimant ainsi complètement l'instabilité de l'ordre.

    Cela signifie que TypeScript 6 et 7 peuvent parfois afficher un ordre différent. Bien que ces changements d'ordre soient presque toujours bénins, si vous comparez les résultats des compilateurs entre deux exécutions (par exemple, en vérifiant les fichiers de déclaration émis dans 6.0 par rapport à 7.0), ces différents ordres peuvent produire beaucoup de bruit, ce qui rend difficile l'évaluation de l'exactitude. Parfois, cependant, vous pouvez constater un changement dans l'ordre qui provoque l'apparition ou la disparition d'une erreur de type, ce qui peut être encore plus déroutant.

    Pour remédier à cette situation, dans la version 6.0, vous pouvez spécifier le nouveau drapeau --stableTypeOrdering. Cela permet d'aligner le comportement de classement des types de la version 6.0 sur celui de la version 7.0, réduisant ainsi le nombre de différences entre les deux bases de code. Notez que nous ne recommandons pas nécessairement d'utiliser ce drapeau en permanence, car il peut ralentir considérablement la vérification des types (jusqu'à 25 % selon la base de code).

    Si vous rencontrez une erreur de type en utilisant --stableTypeOrdering, cela est généralement dû à des différences d'inférence. L'inférence précédente sans --stableTypeOrdering fonctionnait sur la base de l'ordre actuel des types dans votre programme. Pour remédier à cela, il est souvent utile de fournir un type explicite quelque part. Il s'agit généralement d'un argument de type

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    - someFunctionCall(/*...*/);
    + someFunctionCall<SomeExplicitType>(/*...*/);



    ou d'une annotation de variable pour un argument que vous souhaitez passer dans un appel.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    - const someVariable = { /*... some complex object ...*/ };
    + const someVariable: SomeExplicitType = { /*... some complex object ...*/ };
     
    someFunctionCall(someVariable);

    Notez que cet indicateur est uniquement destiné à aider à diagnostiquer les différences entre les versions 6.0 et 7.0. Il n'est pas destiné à être utilisé comme fonctionnalité à long terme.

    Préparation pour TypeScript 7.0

    Outre ces améliorations, cette version apporte les mises à jour suivantes :

    - Option es2025 pour target et lib,
    - Nouveaux types pour Temporal
    - Nouveaux types pour les méthodes « upsert » (alias getOrInsert)
    - la fonction RegExp.escape,
    - La bibliothèque dom contient désormais dom.iterable et dom.asynciterable;

    TypeScript 6.0 est conçu comme une version de transition. Bien que les options obsolètes dans TypeScript 6.0 continueront de fonctionner sans erreur lorsque « ignoreDeprecations » : « 6.0 » est défini, ces options seront entièrement supprimées dans TypeScript 7.0 (le port TypeScript natif). En ce qui concerne le calendrier, l'équipe Typescript prévoit que TypeScript 7.0 suivra peu après TypeScript 6.0.

    Source : Annonce Typescript 6.0 RC

    Et vous ?

    Pensez-vous que cette version est crédible ou pertinente ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    Un TypeScript 10x plus rapide : Anders Hejlsberg, architecte principal de Microsoft pour TypeScript, présente un nouveau portage de TypeScript qui offrira aux développeurs un outil de haute performance

    TypeScript se tourne vers Gopher : Microsoft mise sur Go pour multiplier la vitesse par 10, par Kush Creates

    Refuser TypeScript est un signal que vous ne vous souciez pas de la qualité du code, par Robert Vitonsky
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  3. #3
    Communiqués de presse

    Femme Profil pro
    Traductrice Technique
    Inscrit en
    Juin 2023
    Messages
    2 797
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Traductrice Technique

    Informations forums :
    Inscription : Juin 2023
    Messages : 2 797
    Par défaut Microsoft annonce la version stable de TypeScript 6.0
    Microsoft annonce TypeScript 6.0 apportant des améliorations aux fonctions sensibles au contexte, la prise en charge des importations de sous-chemins et des changements pour préparer TypeScript 7.0

    Microsoft annonce TypeScript 6.0. Voici quelques-uns des points forts de cette version : moins de sensibilité au contexte pour les fonctions sans this, importations de sous-chemins commençant par #/, combinaison de --moduleResolution bundler avec --module commonjs, le drapeau --stableTypeOrdering, l'option es2025 pour target et lib, entre autres. TypeScript 6.0 est une version unique en son genre, car son équipe a l'intention d'en faire la dernière version basée sur le code source JavaScript actuel. Comme annoncé en 2025, ils travaillent sur un nouveau code source pour le compilateur TypeScript et le service de langage écrit en Go qui tire parti de la vitesse du code natif et du multithreading à mémoire partagée.

    Si vous ne connaissez pas encore TypeScript, il s'agit d'un langage qui s'appuie sur JavaScript en y ajoutant une syntaxe de typage, ce qui permet de détecter les erreurs grâce à la vérification des types et offre des outils d'édition avancés. L'écriture de types dans le code permet d'expliquer l'intention et de faire vérifier le code par d'autres outils pour détecter les erreurs comme les fautes de frappe, les problèmes avec null et undefined, et plus encore. Les types alimentent également les outils d'édition de TypeScript, comme l'auto-complétion, la navigation dans le code et les refactorisations que vous pouvez voir dans des éditeurs tels que Visual Studio et VS Code. En fait, TypeScript et son écosystème alimentent l'expérience JavaScript dans ces deux éditeurs également.

    TypeScript 6.0 est une version unique en ce sens car il s'agit la dernière version basée sur la base de code JavaScript actuelle. Comme annoncé en 2025, son équipe de développement travaille sur une nouvelle base de code pour le compilateur TypeScript et le service de langage, écrite en Go, qui tire parti de la vitesse du code natif et du multithreading à mémoire partagée. Cette nouvelle base de code servira de fondement à TypeScript 7.0 et aux versions suivantes.

    TypeScript 6.0 fait office de passerelle entre TypeScript 5.9 et 7.0. À ce titre, la plupart des changements apportés à TypeScript 6.0 visent à faciliter l'alignement et à préparer l'adoption de TypeScript 7.0. Cela peut paraître surprenant, mais TypeScript 7.0 est en réalité sur le point d'être achevé. Vous pouvez l'essayer dans Visual Studio Code ou l'installer depuis npm. En fait, si vous êtes en mesure d'adopter TypeScript 6.0, il est encouragé à essayer les aperçus natifs de TypeScript 7.0. Cela dit, TypeScript 6.0 comporte certaines nouvelles fonctionnalités et améliorations qui ne concernent pas uniquement l'alignement.


    Quelles sont les nouveautés depuis la version bêta et la version RC ?

    Début mars, Microsoft annonce la sortie de la version Release Candidate (RC) de TypeScript 6.0. Depuis la version bêta de TypeScript 6.0, ils ont apporté quelques modifications notables, principalement pour aligner sur le comportement de TypeScript 7.0.

    L'une de ces modifications concerne la vérification des types pour les expressions de fonction dans les appels génériques, en particulier celles apparaissant dans des expressions JSX génériques. Cela permettra généralement de détecter davantage de bogues dans le code existant, même si vous constaterez peut-être que certains appels génériques nécessitent un argument de type explicite.

    Ils ont également étendu la dépréciation de la syntaxe d'assertion d'importation (c'est-à-dire import ... assert {...}) aux appels import() tels que import(..., { assert: {...}}). Enfin, ils ont mis à jour les types DOM afin de refléter les dernières normes web, y compris quelques ajustements apportés aux API temporelles.

    Voici les principales améliorations de cette version :

    Moins de sensibilité au contexte pour les fonctions sans this

    Lorsque les paramètres n'ont pas de types explicites écrits, TypeScript peut généralement les déduire en fonction d'un type attendu, ou même à partir d'autres arguments dans le même appel de fonction.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works, no issues.
    callIt({
        produce: (x: number) => x * 2,
        consume: y => y.toFixed(),
    });
     
    // Works, no issues even though the order of the properties is flipped.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });



    Ici, TypeScript peut déduire le type de y dans la fonction consume en se basant sur le T déduit de la fonction produce, quel que soit l'ordre des propriétés. Mais qu'en est-il si ces fonctions étaient écrites en utilisant la syntaxe de méthode au lieu de la syntaxe de fonction fléchée ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    declare function callIt<T>(obj: {
        produce: (x: number) => T,
        consume: (y: T) => void,
    }): void;
     
    // Works fine, `x` is inferred to be a number.
    callIt({
        produce(x: number) { return x * 2; },
        consume(y) { return y.toFixed(); },
    });
     
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Curieusement, le deuxième appel à callIt entraîne une erreur, car TypeScript n'est pas en mesure de déduire le type de y dans la méthode consume. Ce qui se passe ici, c'est que lorsque TypeScript essaie de trouver des candidats pour T, il ignore d'abord les fonctions dont les paramètres n'ont pas de types explicites. Il procède ainsi parce que certaines fonctions peuvent avoir besoin que le type déduit de T soit correctement vérifié. Dans notre cas, nous avons besoin de connaître le type de T pour analyser notre fonction consume.

    Ces fonctions sont appelées fonctions sensibles au contexte, c'est-à-dire des fonctions dont les paramètres n'ont pas de types explicites. Au final, le système de types devra déterminer les types de ces paramètres, mais cela va quelque peu à l'encontre du fonctionnement de la déduction dans les fonctions génériques, car les deux « tirent » les types dans des directions différentes.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function callFunc<T>(callback: (x: T) => void, value: T) {
        return callback(value);
    }
     
    callFunc(x => x.toFixed(), 42);
    //       ^
    // We need to figure out the type of `x` here,
    // but we also need to figure out the type of `T` to check the callback.



    Pour résoudre ce problème, TypeScript ignore les fonctions sensibles au contexte lors de l'inférence des arguments de type et vérifie et infère d'abord à partir d'autres arguments. Si le fait d'ignorer les fonctions sensibles au contexte ne fonctionne pas, l'inférence se poursuit simplement sur tous les arguments non vérifiés, en allant de gauche à droite dans la liste des arguments. Dans l'exemple ci-dessus, TypeScript ignorera le rappel lors de l'inférence pour T, mais examinera ensuite le deuxième argument, 42, et en déduira que T est un number. Ensuite, lorsqu'il reviendra vérifier le rappel, il aura un type contextuel de (x: nombre) => void, ce qui lui permettra de déduire que [c]x[/B] est également un number.

    Que se passe-t-il donc dans nos exemples précédents ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Arrow syntax - no errors.
    callIt({
        consume: y => y.toFixed(),
        produce: (x: number) => x * 2,
    });
     
    // Method syntax - errors!
    callIt({
        consume(y) { return y.toFixed(); },
        //                  ~
        // error: 'y' is of type 'unknown'.
     
        produce(x: number) { return x * 2; },
    });



    Dans les deux exemples, produce est assignée à une fonction avec un paramètre x explicitement typé. Ne devraient-ils pas être vérifiés de manière identique ?

    La question est subtile : la plupart des fonctions (comme celles qui utilisent la syntaxe de méthode) ont un paramètre this implicite, mais ce n'est pas le cas des fonctions fléchées. Toute utilisation de this pourrait nécessiter de « tirer » sur le type de T. Par exemple, connaître le type de l'objet littéral contenant pourrait à son tour nécessiter le type de consume, qui utilise T.

    Mais nous n'utilisons pas this ! Bien sûr, la fonction peut avoir une valeur this lors de l'exécution, mais elle n'est jamais utilisée !

    TypeScript 6.0 en tient compte lorsqu'il décide si une fonction est sensible au contexte ou non. Si this n'est jamais réellement utilisé dans une fonction, alors il n'est pas considéré comme sensible au contexte. Cela signifie que ces fonctions seront considérées comme ayant une priorité plus élevée en matière d'inférence de type, et tous nos exemples ci-dessus fonctionnent désormais !

    Importations de sous-chemins commençant par #/

    Lorsque Node.js a ajouté la prise en charge des modules, il a ajouté une fonctionnalité appelée « importations de sous-chemins ». Il s'agit essentiellement d'un champ appelé imports qui permet aux paquets de créer des alias internes pour les modules au sein de leur paquet.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#root": "./dist/index.js",
            "#root/*": "./dist/*"
        }
    }



    Cela permet aux modules de my-package d'importer à partir de #root au lieu d'avoir à utiliser un chemin relatif tel que ../../index.js, et permet essentiellement à tout autre module d'écrire quelque chose comme

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "#root/utils.js";



    au lieu d'utiliser un chemin relatif tel que celui ci-dessous.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    import * as utils from "../../utils.js";



    Un inconvénient mineur de cette fonctionnalité est que les développeurs devaient toujours écrire quelque chose après le # lorsqu'ils spécifiaient une importation de sous-chemin. Ici, nous avons utilisé root, mais cela est un peu inutile puisqu'il n'y a pas d'autre répertoire que ./dist/Les développeurs qui ont utilisé des bundlers sont également habitués à utiliser le mappage de chemins pour éviter les longs chemins relatifs. Une convention courante avec les bundlers consiste à utiliser un simple @/ comme préfixe. Malheureusement, les importations de sous-chemins ne pouvaient pas commencer par #/, ce qui causait beaucoup de confusion pour les développeurs qui essayaient de les adopter dans leurs projets.

    Mais plus récemment, Node.js a ajouté la prise en charge des importations de sous-chemins commençant par #/. Cela permet aux paquets d'utiliser un simple préfixe #/ pour leurs importations de sous-chemins sans avoir à ajouter de segment supplémentaire.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
        "name": "my-package",
        "type": "module",
        "imports": {
            "#": "./dist/index.js",
            "#/*": "./dist/*"
        }
    }



    Cette fonctionnalité est prise en charge dans les nouvelles versions de Node.js 20. TypeScript la prend donc désormais en charge dans les options node20, nodenext et bundler pour le paramètre --moduleResolution.

    Combinaison de --moduleResolution bundler avec --module commonjs

    Le paramètre --moduleResolution bundler de TypeScript ne pouvait auparavant être utilisé qu'avec --module esnext ou --module preserve ; cependant, avec la dépréciation de --moduleResolution node (alias --moduleResolution node10), cette nouvelle combinaison est souvent la voie de mise à niveau la plus appropriée pour de nombreux projets.

    Les projets voudront souvent planifier une migration vers l'un des deux éléments suivants

    - --module preserve et --moduleResolution bundler,
    - --module nodenext,

    en fonction du type de projet (par exemple, application web groupée, application Bun ou application Node.js).

    Le drapeau --stableTypeOrdering

    Dans le cadre du travail continu sur le portage natif de TypeScript, cette version introduit un nouveau drapeau appelé --stableTypeOrdering destiné à faciliter les migrations de la version 6.0 à la version 7.0.

    Aujourd'hui, TypeScript attribue des identifiants de type (numéros de suivi internes) aux types dans l'ordre où ils apparaissent, et utilise ces identifiants pour trier les types d'union de manière cohérente. Un processus similaire s'applique aux propriétés. Par conséquent, l'ordre dans lequel les éléments sont déclarés dans un programme peut avoir des effets surprenants sur des éléments tels que l'émission de déclarations.

    Prenons par exemple l'émission de déclaration de ce fichier :

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Input: some-file.ts
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 100 | 500;
    //                                               ^^^^^^^^^
    //             Note the order of this union: 100, then 500.



    Si nous ajoutons const sans rapport au-dessus de foo, l'émission de déclaration change :

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Input: some-file.ts
    const x = 500;
    export function foo(condition: boolean) {
        return condition ? 100 : 500;
    }
     
    // Output: some-file.d.ts
    export declare function foo(condition: boolean): 500 | 100;
    //                                               ^^^^^^^^^
    //                           Note the change in order here.



    Cela se produit parce que le type littéral 500 obtient un identifiant de type inférieur à 100, car il a été traité en premier lors de l'analyse de la déclaration de la const x. Dans de très rares cas, ce changement d'ordre peut même entraîner l'apparition ou la disparition d'erreurs en fonction de l'ordre de traitement du programme, mais en général, c'est principalement dans les fichiers de déclaration émis ou dans la façon dont les types sont affichés dans votre éditeur que vous remarquerez cet ordre.

    L'une des principales améliorations architecturales de TypeScript 7 est la vérification parallèle des types, qui réduit considérablement le temps de vérification global. Cependant, le parallélisme pose un défi : lorsque différents vérificateurs de types visitent les nœuds, les types et les symboles dans des ordres différents, les identifiants internes attribués à ces constructions deviennent non déterministes. Cela conduit à des résultats non déterministes prêtant à confusion, où deux fichiers au contenu identique dans le même programme peuvent produire des fichiers de déclaration différents, voire calculer des erreurs différentes lors de l'analyse du même fichier. Pour remédier à cela, TypeScript 7.0 trie ses objets internes (par exemple, les types et les symboles) selon un algorithme déterministe basé sur le contenu de l'objet. Cela garantit que tous les vérificateurs rencontrent le même ordre d'objets, indépendamment de la manière et du moment où ils ont été créés. En conséquence, dans l'exemple donné, TypeScript 7 affichera toujours 100 | 500, supprimant ainsi complètement l'instabilité de l'ordre.

    Cela signifie que TypeScript 6 et 7 peuvent parfois afficher un ordre différent. Bien que ces changements d'ordre soient presque toujours bénins, si vous comparez les résultats des compilateurs entre deux exécutions (par exemple, en vérifiant les fichiers de déclaration émis dans 6.0 par rapport à 7.0), ces différents ordres peuvent produire beaucoup de bruit, ce qui rend difficile l'évaluation de l'exactitude. Parfois, cependant, vous pouvez constater un changement dans l'ordre qui provoque l'apparition ou la disparition d'une erreur de type, ce qui peut être encore plus déroutant.

    Pour remédier à cette situation, dans la version 6.0, vous pouvez spécifier le nouveau drapeau --stableTypeOrdering. Cela permet d'aligner le comportement de classement des types de la version 6.0 sur celui de la version 7.0, réduisant ainsi le nombre de différences entre les deux bases de code. Notez qu'il n'est pas nécessairement recommandé d'utiliser ce drapeau en permanence, car il peut ralentir considérablement la vérification des types (jusqu'à 25 % selon la base de code).

    Si vous rencontrez une erreur de type en utilisant --stableTypeOrdering, cela est généralement dû à des différences d'inférence. L'inférence précédente sans --stableTypeOrdering fonctionnait sur la base de l'ordre actuel des types dans votre programme. Pour remédier à cela, il est souvent utile de fournir un type explicite quelque part. Il s'agit généralement d'un argument de type

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    - someFunctionCall(/*...*/);
    + someFunctionCall<SomeExplicitType>(/*...*/);



    ou d'une annotation de variable pour un argument que vous souhaitez passer dans un appel.

    Code Typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    - const someVariable = { /*... some complex object ...*/ };
    + const someVariable: SomeExplicitType = { /*... some complex object ...*/ };
     
    someFunctionCall(someVariable);

    Notez que cet indicateur est uniquement destiné à aider à diagnostiquer les différences entre les versions 6.0 et 7.0. Il n'est pas destiné à être utilisé comme fonctionnalité à long terme.

    Option es2025 pour target et lib.

    TypeScript 6.0 prend désormais en charge l'option es2025 pour les cibles target et lib. Bien qu'il n'y ait pas de nouvelles fonctionnalités du langage JavaScript dans ES2025, cette nouvelle cible ajoute de nouveaux types pour les API intégrées (par exemple, RegExp.escape) et transfère quelques déclarations d'esnext vers es2025 (par exemple, Promise.try, les méthodes Iterator et les méthodes Set).

    Nouveaux types pour Temporal.

    La proposition Temporal tant attendue a atteint la phase 4 et fera partie d'une future norme ECMAScript. TypeScript 6.0 inclut désormais des types intégrés pour l'API Temporal, vous pouvez donc commencer à l'utiliser dès aujourd'hui dans votre code TypeScript via --target esnext ou "lib" : ["esnext"] (ou l'option plus granulaire esnext.temporal).

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let yesterday = Temporal.Now.instant().subtract({
        hours: 24,
    });
     
    let tomorrow = Temporal.Now.instant().add({
        hours: 24,
    });
     
    console.log(`Yesterday: ${yesterday}`);
    console.log(`Tomorrow: ${tomorrow}`);



    Temporal est déjà utilisable dans plusieurs environnements d'exécution, et avec son statut de phase 4, il fait désormais officiellement partie du langage JavaScript.

    Nouveaux types pour les méthodes "upsert" (alias getOrInsert)

    Une pratique courante avec les Maps consiste à vérifier si une clé existe et, si ce n'est pas le cas, à définir et récupérer une valeur par défaut.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function processOptions(compilerOptions: Map<string, unknown>) {
        let strictValue: unknown;
        if (compilerOptions.has("strict")) {
            strictValue = compilerOptions.get("strict");
        }
        else {
            strictValue = true;
            compilerOptions.set("strict", strictValue);
        }
        // ...
    }



    Ce modèle peut s'avérer fastidieux. La proposition "upsert" d'ECMAScript a récemment atteint le stade 4 et introduit deux nouvelles méthodes sur Map et WeakMap :

    - getOrInsert,
    - getOrInsertComputed.

    Ces méthodes ont été ajoutées à la bibliothèque esnext afin que vous puissiez commencer à les utiliser immédiatement dans TypeScript 6.0.

    Avec getOrInsert, ils peuvent remplacer le code ci-dessus par ce qui suit :

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function processOptions(compilerOptions: Map<string, unknown>) {
        let strictValue = compilerOptions.getOrInsert("strict", true);
        // ...
    }



    getOrInsertComputed fonctionne de manière similaire, mais est destiné aux cas où le calcul de la valeur par défaut peut être coûteux (par exemple, s'il nécessite de nombreux calculs, des allocations de mémoire ou des opérations d'E/S synchrones de longue durée). À la place, il prend en charge un callback qui ne sera appelé que si la clé n'existe pas déjà.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    someMap.getOrInsertComputed("someKey", () => {
        return computeSomeExpensiveValue(/*...*/);
    });



    Cette fonction de rappel reçoit également la clé en argument, ce qui peut être utile dans les cas où la valeur par défaut est basée sur la clé.

    RegExp.escape

    Lors de la construction d'une chaîne littérale à faire correspondre dans une expression régulière, il est important d'échapper les caractères spéciaux des expressions régulières tels que *, +, ?, (, ), etc. La proposition ECMAScript "RegExp Escaping" a atteint la phase 4 et introduit une nouvelle fonction RegExp.escape qui s'en charge pour vous.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function matchWholeWord(word: string, text: string) {
        const escapedWord = RegExp.escape(word);
        const regex = new RegExp(`\\b${escapedWord}\\b`, "g");
        return text.match(regex);
    }



    RegExp.escape est disponible dans la bibliothèque es2025, vous pouvez donc commencer à l'utiliser dès aujourd'hui dans TypeScript 6.0.

    La bibliothèque dom contient désormais dom.iterable et dom.asynciterable.

    L'option lib de TypeScript vous permet de spécifier les déclarations globales dont dispose votre runtime cible. L'une des options est dom pour représenter les environnements web (c'est-à-dire les navigateurs, qui implémentent les API DOM). Auparavant, les API DOM étaient partiellement divisées en dom.iterable et dom.asynciterable pour les environnements qui ne prenaient pas en charge Iterable et AsyncIterables. Cela signifiait que vous deviez ajouter explicitement dom.iterable pour utiliser les méthodes d'itération sur les collections DOM telles que NodeList ou HTMLCollection.

    Dans TypeScript 6.0, le contenu de lib.dom.iterable.d.ts et lib.dom.asynciterable.d.ts est entièrement inclus dans lib.dom.d.ts. Vous pouvez toujours référencer dom.iterable et dom.asynciterable dans le tableau "lib" de votre fichier de configuration, mais il s'agit désormais de fichiers vides.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Before TypeScript 6.0, this required "lib": ["dom", "dom.iterable"]
    // Now it works with just "lib": ["dom"]
    for (const element of document.querySelectorAll("div")) {
        console.log(element.textContent);
    }

    Il s'agit d'une amélioration visant à faciliter l'utilisation qui élimine une source courante de confusion, car aucun navigateur moderne majeur ne manque de ces capacités. Si vous incluiez déjà à la fois dom et dom.iterable, vous pouvez désormais simplifier votre code en utilisant uniquement dom.

    Changements majeurs et éléments obsolètes dans TypeScript 6.0

    TypeScript 6.0 marque une version de transition majeure, conçue pour préparer les développeurs à TypeScript 7.0, le futur portage natif du compilateur TypeScript. Bien que TypeScript 6.0 reste entièrement compatible avec vos connaissances actuelles de TypeScript et conserve la compatibilité API avec TypeScript 5.9, cette version introduit un certain nombre de changements majeurs et de dépréciations qui reflètent l'évolution de l'écosystème JavaScript et préparent le terrain pour TypeScript 7.0.

    Au cours des deux années qui ont suivi la sortie de TypeScript 5.0, Microsoft rapporte des changements continus dans la manière dont les développeurs écrivent et déploient du JavaScript :

    - Pratiquement tous les environnements d'exécution sont désormais « evergreen ». Les véritables environnements hérités (ES5) sont de plus en plus rares.

    - Les bundlers et ESM sont devenus les cibles de modules les plus courantes pour les nouveaux projets, bien que CommonJS reste une cible majeure. AMD et les autres systèmes de modules userland dans le navigateur sont beaucoup plus rares qu'ils ne l'étaient en 2012.

    - Presque tous les paquets peuvent être utilisés via un système de modules. Les paquets UMD existent toujours, mais pratiquement aucun nouveau code n’est disponible uniquement sous forme de variable globale.

    - tsconfig.json est devenu un mécanisme de configuration quasi universel.

    - L’engouement pour un typage « plus strict » ne cesse de croître.

    - Les performances de compilation de TypeScript sont une priorité absolue. Malgré les avancées de TypeScript 7, les performances doivent toujours rester un objectif clé, et les options qui ne peuvent pas être prises en charge de manière performante doivent être justifiées de manière plus rigoureuse.

    TypeScript 6.0 et 7.0 ont donc été conçus en tenant compte de ces réalités. Pour TypeScript 6.0, ces dépréciations peuvent être ignorées en définissant "ignoreDeprecations" : "6.0" dans votre tsconfig ; notez toutefois que TypeScript 7.0 ne prendra en charge aucune de ces options dépréciées.

    Certaines modifications nécessaires peuvent être effectuées automatiquement à l'aide d'un codemod ou d'un outil. Par exemple, l'outil expérimental ts5to6 peut ajuster automatiquement les paramètres baseUrl et rootDir dans l'ensemble de votre base de code.

    Se préparer à TypeScript 7.0

    TypeScript 6.0 est conçu comme une version de transition. Bien que les options obsolètes dans TypeScript 6.0 continuent de fonctionner sans erreur lorsque "ignoreDeprecations" : "6.0" est défini, ces options seront entièrement supprimées dans TypeScript 7.0 (le portage natif de TypeScript). Si vous voyez des avertissements de dépréciation après la mise à niveau vers TypeScript 6.0, il est recommandé vivement de les traiter avant d'adopter TypeScript 7.0 (ou d'essayer les aperçus natifs) dans votre projet.

    Maintenant que TypeScript 6.0 est disponible sur npm, l'équipe va se concentrer sur la stabilisation de TypeScript 7.0. Cela est beaucoup plus proche qu'il n'y paraît : ils prévoient une sortie d'ici quelques mois. TypeScript 6.0 reste une version stable que vous devriez pouvoir adopter dès aujourd’hui, et elle inclut un certain nombre d’améliorations et de nouvelles fonctionnalités que vous pouvez commencer à utiliser immédiatement.

    Source : Annonce de TypeScript 6.0

    Et vous ?

    Pensez-vous que cette version est crédible ou pertinente ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    Microsoft annonce la version Beta de TypeScript 6.0 apportant des améliorations aux fonctions sensibles au contexte ainsi que la prise en charge des importations de sous-chemins

    Un TypeScript 10x plus rapide : Anders Hejlsberg, architecte principal de Microsoft pour TypeScript, présente un nouveau portage de TypeScript qui offrira aux développeurs un outil de haute performance

    Refuser TypeScript est un signal que vous ne vous souciez pas de la qualité du code, par Robert Vitonsky
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Microsoft annonce la version candidate de TypeScript 5.9
    Par Jade Emy dans le forum TypeScript
    Réponses: 0
    Dernier message: 30/07/2025, 09h02
  2. Réponses: 0
    Dernier message: 03/10/2024, 10h55
  3. Réponses: 0
    Dernier message: 26/08/2022, 19h47
  4. Microsoft annonce la disponibilité de la version stable de TypeScript 2.7
    Par Stéphane le calme dans le forum TypeScript
    Réponses: 0
    Dernier message: 22/01/2018, 17h44
  5. Microsoft annonce la version 1.5 alpha de TypeScript
    Par yahiko dans le forum TypeScript
    Réponses: 13
    Dernier message: 01/05/2015, 12h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo