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 disponibilité de TypeScript 5.7 Beta


Sujet :

TypeScript

  1. #1
    Communiqués de presse

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

    Informations professionnelles :
    Activité : Traductrice Technique

    Informations forums :
    Inscription : Juin 2023
    Messages : 1 669
    Points : 116 583
    Points
    116 583
    Par défaut Microsoft annonce la disponibilité de TypeScript 5.7 Beta
    Microsoft annonce la disponibilité de TypeScript 5.7 Beta apportant des améliorations à la vérification des variables jamais initialisées et une vérification plus rapide de la propriété d'un projet

    Microsoft annonce la disponibilité de TypeScript 5.7 Beta. Voici quelques mises à jour que TypeScript 5.7 apporte : vérification des variables jamais initialisées, réécriture de chemin pour les chemins relatifs, vérifications plus rapides de la propriété du projet dans les éditeurs pour les projets composites et d'autres changements notables.

    TypeScript est un langage de programmation de haut niveau, libre et gratuit, développé par Microsoft, qui ajoute à JavaScript un typage statique avec des annotations de type optionnelles. Il est conçu pour le développement de grandes applications et se transpose à JavaScript. Comme TypeScript est un surensemble de JavaScript, tous les programmes JavaScript sont syntaxiquement valides en TypeScript, mais ils peuvent ne pas vérifier le type pour des raisons de sécurité.

    TypeScript 5.7 Beta est désormais disponible. À ce stade, TypeScript 5.7 serait "stable en termes de fonctionnalités". TypeScript 5.7 se concentrera sur les corrections de bogues, le polissage et certaines fonctionnalités d'édition à faible risque. Une version candidate sera disponible dans un peu plus d'un mois, suivie d'une version stable peu après.

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

    Voici quelques mises à jour de cette version :

    Vérification des variables jamais initialisées

    Depuis longtemps, TypeScript est capable de détecter les problèmes lorsqu'une variable n'a pas encore été initialisée dans toutes les branches précédentes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let result: number
    if (someCondition()) {
        result = doSomeWork();
    }
    else {
        let temporaryWork = doSomeWork();
        temporaryWork *= 2;
        // forgot to assign to 'result'
    }
     
    console.log(result); // error: Variable 'result' is used before being assigned.


    Malheureusement, dans certains cas, cette analyse ne fonctionne pas. Par exemple, si la variable est accédée dans une fonction séparée, le système de types ne sait pas quand la fonction sera appelée, et adopte une vue "optimiste" selon laquelle la variable sera initialisée.

    Code : 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
    function foo() {
        let result: number
        if (someCondition()) {
            result = doSomeWork();
        }
        else {
            let temporaryWork = doSomeWork();
            temporaryWork *= 2;
            // forgot to assign to 'result'
        }
     
        printResult();
     
        function printResult() {
            console.log(result); // no error here.
        }
    }


    Bien que TypeScript 5.7 soit encore indulgent envers les variables qui ont pu être initialisées, le système de types est capable de signaler des erreurs lorsque les variables n'ont jamais été initialisées du tout.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function foo() {
        let result: number
     
        // do work, but forget to assign to 'result'
     
        function printResult() {
            console.log(result); // error: Variable 'result' is used before being assigned.
        }
    }


    Réécriture de chemin pour les chemins relatifs

    Il existe plusieurs outils et moteurs d'exécution qui vous permettent d'exécuter du code TypeScript "sur place", ce qui signifie qu'ils ne nécessitent pas d'étape de compilation qui génère des fichiers JavaScript de sortie. Par exemple, ts-node, tsx, Deno et Bun permettent tous d'exécuter des fichiers .ts directement. Plus récemment, Node.js a étudié ce support avec --experimental-transform-types et --experimental-strip-types. C'est extrêmement pratique car cela permet d'itérer plus rapidement sans avoir à se soucier de relancer une tâche de construction.

    Il y a cependant une certaine complexité à prendre en compte lors de l'utilisation de ces modes. Pour être compatible avec tous ces outils, un fichier TypeScript importé "sur-place" doit être importé avec l'extension TypeScript appropriée au moment de l'exécution. Par exemple, pour importer un fichier appelé foo.ts, nous devons écrire ce qui suit dans le nouveau support expérimental de Node :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // main.ts
     
    import * as foo from "./foo.ts"; // <- we need foo.ts here, not foo.js


    Typiquement, TypeScript émettrait une erreur si nous faisions cela, parce qu'il s'attend à ce que nous importions le fichier de sortie. Parce que certains outils autorisent les importations .ts, TypeScript a supporté ce style d'importation avec une option appelée --allowImportingTsExtensions depuis un certain temps. Cela fonctionne bien, mais que se passe-t-il si nous avons besoin de générer des fichiers .js à partir de ces fichiers .ts ? C'est une exigence pour les auteurs de bibliothèques qui devront être en mesure de distribuer uniquement des fichiers .js, mais jusqu'à présent TypeScript a évité de réécrire les chemins.

    Pour supporter ce scénario, cette version apporte une nouvelle option de compilation appelée --rewriteRelativeImportExtensions. Lorsqu'un chemin d'importation est relatif (commence par ./ ou ../), se termine par une extension TypeScript (.ts, .tsx, .mts, .cts), et est un fichier sans déclaration, le compilateur réécrira le chemin vers l'extension JavaScript correspondante (.js, .jsx, .mjs, .cjs).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Under --rewriteRelativeImportExtensions...
     
    // these will be rewritten.
    import * as foo from "./foo.ts";
    import * as bar from "../someFolder/bar.mts";
     
    // these will NOT be rewritten in any way.
    import * as a from "./foo";
    import * as b from "some-package/file.ts";
    import * as c from "@some-scope/some-package/file.ts";
    import * as d from "#/file.ts";
    import * as e from "./file.js";


    Cela permet d'écrire du code TypeScript qui peut être exécuté sur place, puis compilé en JavaScript.

    TypeScript évitait généralement de réécrire les chemins. Il y a plusieurs raisons à cela, mais la plus évidente est l'importation dynamique. Si un développeur écrit ce qui suit, il n'est pas négligeable de gérer le chemin que import reçoit. En fait, il est impossible de remplacer le comportement de import dans les dépendances.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getPath() {
        if (Math.random() < 0.5) {
            return "./foo.ts";
        }
        else {
            return "./foo.js";
        }
    }
     
    let myImport = await import(getPath());


    Un autre problème est que seuls les chemins "relatifs" sont réécrits, et ils sont écrits "naïvement". Cela signifie que tout chemin qui s'appuie sur baseUrl et path de TypeScript ne sera pas réécrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // tsconfig.json
     
    {
        "compilerOptions": {
            "module": "nodenext",
            // ...
            "paths": {
                "@/*": ["./src/*"]
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Won't be transformed, won't work.
    import * as utilities from "@/utilities.ts";


    Il en va de même pour tout chemin qui pourrait être résolu par les champs exports et imports d'un package.json.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // package.json
    {
        "name": "my-package",
        "imports": {
            "#root/*": "./dist/*"
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Won't be transformed, won't work.
    import * as utilities from "#root/utilities.ts";


    Par conséquent, si vous avez utilisé une disposition de type espace de travail avec plusieurs paquets se référençant les uns les autres, vous devrez peut-être utiliser des exportations conditionnelles avec des conditions personnalisées à portée pour que cela fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // my-package/package.json
     
    {
        "name": "my-package",
        "exports": {
            ".": {
                "@my-package/development": "./src/index.ts",
                "import": "./lib/index.js"
            },
            "./*": {
                "@my-package/development": "./src/*.ts",
                "import": "./lib/*.js"
            }
        }
    }


    Chaque fois que vous voulez importer les fichiers .ts, vous pouvez l'exécuter avec node --conditions=@my-package/development.

    Notez le "namespace" ou "scope" utilisé pour la condition @my-package/development. Il s'agit d'une solution de fortune pour éviter les conflits avec les dépendances qui pourraient également utiliser la condition development. Si tout le monde livre un development dans son paquet, alors la résolution peut essayer de se résoudre à un fichier .ts, ce qui ne fonctionnera pas nécessairement.


    Support de --target es2024 et --lib es2024

    TypeScript 5.7 supporte désormais --target es2024, qui permet aux utilisateurs de cibler les runtimes ECMAScript 2024. Cette cible permet principalement de spécifier la nouvelle --lib es2024 qui contient de nombreuses fonctionnalités pour SharedArrayBuffer et ArrayBuffer, Object.groupBy, Map.groupBy, Promise.withResolvers, et plus encore. Il déplace également Atomics.waitAsync de --lib es2022 à --lib es2024.

    Notez que dans le cadre des changements apportés à SharedArrayBuffer et ArrayBuffer, les deux divergent un peu. Pour combler le fossé et préserver le type de tampon sous-jacent, tous les TypedArrays (comme Uint8Array et d'autres) sont maintenant aussi génériques.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> {
        // ...
    }


    Chaque TypedArray contient maintenant un paramètre de type nommé TArrayBuffer, bien que ce paramètre de type ait un argument de type par défaut afin de se référer à Int32Array sans écrire explicitement Int32Array<ArrayBufferLike>.

    Si vous rencontrez des problèmes dans le cadre de cette mise à jour, vous devrez peut-être mettre à jour @types/node.


    Recherche de fichiers de configuration ancestraux pour la propriété du projet

    Lorsqu'un fichier TypeScript est chargé dans un éditeur utilisant TSServer (comme Visual Studio ou VS Code), l'éditeur essaiera de trouver le fichier tsconfig.json pertinent qui "possède" le fichier. Pour ce faire, il remonte l'arborescence des répertoires à partir du fichier en cours d'édition, à la recherche de tout fichier nommé tsconfig.json.

    Auparavant, cette recherche s'arrêtait au premier fichier tsconfig.json trouvé ; cependant, imaginez une structure de projet comme la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    project/
    ├── src/
    │   ├── foo.ts
    │   ├── foo-test.ts
    │   ├── tsconfig.json
    │   └── tsconfig.test.json
    └── tsconfig.json


    Ici, l'idée est que src/tsconfig.json est le fichier de configuration "principal" du projet, et src/tsconfig.test.json est un fichier de configuration pour l'exécution des tests.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // src/tsconfig.json
    {
        "compilerOptions": {
            "outDir": "../dist"
        },
        "exclude": ["**/*.test.ts"]
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // src/tsconfig.test.json
    {
        "compilerOptions": {
            "outDir": "../dist/test"
        },
        "include": ["**/*.test.ts"],
        "references": [
            { "path": "./tsconfig.json" }
        ]
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // tsconfig.json
    {
        // This is a "workspace-style" or "solution-style" tsconfig.
        // Instead of specifying any files, it just references all the actual projects.
        "files": [],
        "references": [
            { "path": "./src/tsconfig.json" },
            { "path": "./src/tsconfig.test.json" },
        ]
    }


    Le problème ici est que lors de l'édition de foo-test.ts, l'éditeur trouverait project/src/tsconfig.json comme fichier de configuration "propriétaire" - mais ce n'est pas celui voulu ! Si la marche s'arrête à ce point, ce n'est pas forcément souhaitable. La seule façon d'éviter cela était de renommer src/tsconfig.json en quelque chose comme src/tsconfig.src.json, et alors tous les fichiers seraient dirigés vers le fichier de premier niveau tsconfig.json qui fait référence à tous les projets possibles.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    project/
    ├── src/
    │   ├── foo.ts
    │   ├── foo-test.ts
    │   ├── tsconfig.src.json
    │   └── tsconfig.test.json
    └── tsconfig.json


    Au lieu de forcer les développeurs à procéder ainsi, TypeScript 5.7 continue à remonter l'arborescence des répertoires pour trouver d'autres fichiers tsconfig.json appropriés aux scénarios de l'éditeur. Cela peut apporter plus de flexibilité dans la façon dont les projets sont organisés et dont les fichiers de configuration sont structurés.


    Vérifications plus rapides de la propriété du projet dans les éditeurs pour les projets composites

    Imaginez une grande base de code avec la structure suivante :

    Code : 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
    19
    20
    21
    22
    packages
    ├── graphics/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── sound/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── networking/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── input/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    └── app/
        ├── tsconfig.json
        ├── some-script.js
        └── src/
            └── ...


    Chaque répertoire dans packages est un projet TypeScript séparé, et le répertoire app est le projet principal qui dépend de tous les autres projets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // app/tsconfig.json
    {
        "compilerOptions": {
            // ...
        },
        "include": ["src"],
        "references": [
            { "path": "../graphics/tsconfig.json" },
            { "path": "../sound/tsconfig.json" },
            { "path": "../networking/tsconfig.json" },
            { "path": "../input/tsconfig.json" }
        ]
    }


    Remarquons maintenant que nous avons le fichier some-script.js dans le répertoire app. Lorsque nous ouvrons some-script.js dans l'éditeur, le service de langage TypeScript (qui gère également l'expérience de l'éditeur pour les fichiers JavaScript !) doit déterminer à quel projet appartient le fichier afin d'appliquer les bons paramètres.

    Dans ce cas, le fichier tsconfig.json le plus proche n'inclut pas some-script.js, mais TypeScript va demander "l'un des projets référencés par app/tsconfig.json pourrait-il inclure some-script.js ?". Pour ce faire, TypeScript aurait préalablement chargé chaque projet, un par un, et se serait arrêté dès qu'il aurait trouvé un projet contenant some-script.js ?. Même si some-script.js ? n'est pas inclus dans l'ensemble des fichiers de la racine, TypeScript analysait quand même tous les fichiers d'un projet parce que certains des fichiers de la racine peuvent toujours faire référence à some-script.js ? de manière transitoire.

    Au fil du temps, ce comportement entraînait des réactions extrêmes et imprévisibles dans les bases de code plus importantes. Les développeurs ouvraient des fichiers de script égarés et se retrouvaient à attendre que l'ensemble de leur base de code soit ouvert.

    Heureusement, chaque projet pouvant être référencé par un autre projet (hors espace de travail) doit activer un indicateur appelé composite, qui applique une règle selon laquelle tous les fichiers source d'entrée doivent être connus à l'avance. Ainsi, lors de l'analyse d'un projet composite, TypeScript 5.7 ne vérifiera que si un fichier appartient à l'ensemble de fichiers racine de ce projet. Cela devrait permettre d'éviter ce comportement courant dans le pire des cas.


    Importations JSON validées dans --module nodenext

    Lors de l'importation à partir d'un fichier .json sous --module nodenext, TypeScript appliquera désormais certaines règles pour éviter les erreurs d'exécution.

    Par exemple, un attribut d'importation contenant le type : "json" doit être présent pour toute importation de fichier JSON.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import myConfig from "./myConfig.json";
    //                   ~~~~~~~~~~~~~~~~~
    //  error: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'.
     
    import myConfig from "./myConfig.json" with { type: "json" };
    //                                          ^^^^^^^^^^^^^^^^
    //  This is fine because we provided `type: "json"`


    En plus de cette validation, TypeScript ne génère pas d'exportations "nommées", et le contenu d'une importation JSON n'est accessible que par défaut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //  This is okay:
    import myConfigA from "./myConfig.json" with { type: "json" };
    let version = myConfigA.version;
     
    ///////////
     
    import * as myConfigB from "./myConfig.json" with { type: "json" };
     
    //  This is not:
    let version = myConfig.version;
     
    //  This is okay:
    let version = myConfig.default.version;


    Prise en charge de la mise en cache de la compilation V8 dans Node.js

    Node.js 22 prend en charge une nouvelle API appelée module.enableCompileCache(). Cette API permet au moteur d'exécution de réutiliser une partie du travail d'analyse et de compilation effectué après la première exécution d'un outil.

    TypeScript 5.7 exploite désormais l'API afin de pouvoir commencer à effectuer un travail utile plus tôt. Lors des tests, il a été constaté une accélération de 2,5 fois lors de l'exécution de tsc --version.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Benchmark 1: node ./built/local/_tsc.js --version (*without* caching)
      Time (mean ± σ):     122.2 ms ±   1.5 ms    [User: 101.7 ms, System: 13.0 ms]
      Range (min … max):   119.3 ms … 132.3 ms    200 runs
     
    Benchmark 2: node ./built/local/tsc.js --version  (*with* caching)
      Time (mean ± σ):      48.4 ms ±   1.0 ms    [User: 34.0 ms, System: 11.1 ms]
      Range (min … max):    45.7 ms …  52.8 ms    200 runs
     
    Summary
      node ./built/local/tsc.js --version ran
        2.52 ± 0.06 times faster than node ./built/local/_tsc.js --version


    Source : "Announcing TypeScript 5.7 Beta"

    Et vous ?

    Que pensez-vous de cette mise à jour ?

    Voir aussi :

    Microsoft annonce la disponibilité de TypeScript 5.6, apportant des améliorations à la vérification vraie et nulle non autorisée ainsi que des méthodes d'aide pour les itérateurs

    Cinq vérités inconfortables à propos de TypeScript selon Stefan Baumgartner, auteur de livres sur le langage de programmation

    TypeScript, les types marqués : Produire un moyen de marquer un type, en fournissant un moyen automatisé et facile à utiliser pour rendre un type nominal, par Prosopo
    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
    Chroniqueur Actualités
    Avatar de Anthony
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Novembre 2022
    Messages
    1 274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : Novembre 2022
    Messages : 1 274
    Points : 20 948
    Points
    20 948
    Par défaut Microsoft annonce la Release Candidate de TypeScript 5.7 et apporte plusieurs améliorations
    Microsoft annonce la Release Candidate de TypeScript 5.7 et apporte plusieurs améliorations, dont la réécriture des chemins relatifs et des contrôles pour les variables non initialisées

    Microsoft annonce la disponibilité de la release candidate (RC) de TypeScript 5.7. Cette version introduit des contrôles pour les variables non initialisées, la réécriture des chemins pour les chemins relatifs, le support pour target et lib es2024, et des contrôles améliorés de la propriété du projet dans les éditeurs.

    Pour commencer à utiliser la RC, il est possible de l'obtenir via npm à l'aide de la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    npm install -D typescript@rc


    Nom : Typescript 5.7.PNG
Affichages : 2579
Taille : 35,6 Ko

    Voici un aperçu des nouveautés de TypeScript 5.7.

    Vérification des variables non initialisées

    Depuis longtemps, TypeScript est capable de détecter les problèmes lorsqu'une variable n'a pas encore été initialisée dans toutes les branches précédentes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let result: number
    if (someCondition()) {
        result = doSomeWork();
    }
    else {
        let temporaryWork = doSomeWork();
        temporaryWork *= 2;
        // forgot to assign to 'result'
    }
     
    console.log(result); // error: Variable 'result' is used before being assigned.

    Malheureusement, il y a des endroits où cette analyse ne fonctionne pas. Par exemple, si la variable est accédée dans une fonction séparée, le système de type ne sait pas quand la fonction sera appelée, et prend une vue « optimiste » que la variable sera initialisée.

    Code : 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
    function foo() {
        let result: number
        if (someCondition()) {
            result = doSomeWork();
        }
        else {
            let temporaryWork = doSomeWork();
            temporaryWork *= 2;
            // forgot to assign to 'result'
        }
     
        printResult();
     
        function printResult() {
            console.log(result); // no error here.
        }
    }

    Bien que TypeScript 5.7 soit encore indulgent avec les variables qui ont été éventuellement initialisées, le système de types est capable de signaler des erreurs lorsque les variables n'ont jamais été initialisées du tout.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function foo() {
        let result: number
     
        // do work, but forget to assign to 'result'
     
        function printResult() {
            console.log(result); // error: Variable 'result' is used before being assigned.
        }
    }

    Réécriture de chemin pour les chemins relatifs

    Il existe plusieurs outils et moteurs d'exécution qui permettent d'exécuter du code TypeScript « in-place », ce qui signifie qu'ils ne nécessitent pas d'étape de construction qui génère des fichiers JavaScript de sortie. Par exemple, ts-node, tsx, Deno et Bun permettent tous d'exécuter des fichiers .ts directement. Plus récemment, Node.js a étudié ce support avec --experimental-transform-types et --experimental-strip-types. C'est extrêmement pratique car cela permet d'itérer plus rapidement sans avoir à se soucier de relancer une tâche de construction.

    Il y a cependant une certaine complexité à prendre en compte lors de l'utilisation de ces modes. Pour être compatible avec tous ces outils, un fichier TypeScript importé « in-place » doit être importé avec l'extension TypeScript appropriée au moment de l'exécution. Par exemple, pour importer un fichier appelé foo.ts, il faut écrire ce qui suit dans le nouveau support expérimental de Node :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // main.ts
     
    import * as foo from "./foo.ts"; // <- we need foo.ts here, not foo.js

    Typiquement, TypeScript émettrait une erreur si on le faisait, parce qu'il s'attend à ce qu'on importe le fichier de sortie. Parce que certains outils autorisent les importations .ts, TypeScript a supporté ce style d'importation avec une option appelée --allowImportingTsExtensions depuis un certain temps. Cela fonctionne bien, mais que se passe-t-il si on a besoin de générer des fichiers .js à partir de ces fichiers .ts ? C'est une exigence pour les auteurs de bibliothèques qui devront être en mesure de distribuer uniquement des fichiers .js, mais jusqu'à présent TypeScript a évité de réécrire les chemins.

    Pour prendre en charge ce scénario, une nouvelle option du compilateur a été ajoutée : --rewriteRelativeImportExtensions. Lorsqu'un chemin d'importation est relatif (commence par ./ ou ../), se termine par une extension TypeScript (.ts, .tsx, .mts, .cts), et qu'il s'agit d'un fichier sans déclaration, le compilateur réécrira le chemin vers l'extension JavaScript correspondante (.js, .jsx, .mjs, .cjs).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Under --rewriteRelativeImportExtensions...
     
    // these will be rewritten.
    import * as foo from "./foo.ts";
    import * as bar from "../someFolder/bar.mts";
     
    // these will NOT be rewritten in any way.
    import * as a from "./foo";
    import * as b from "some-package/file.ts";
    import * as c from "@some-scope/some-package/file.ts";
    import * as d from "#/file.ts";
    import * as e from "./file.js";

    Cela permet d'écrire du code TypeScript qui peut être exécuté sur place, puis compilé en JavaScript lorsque tout est prêt.

    Maintenant, il a été noté que TypeScript évitait en général de réécrire les chemins d'accès. Il y a plusieurs raisons à cela, mais la plus évidente est celle des importations dynamiques. Si un développeur écrit ce qui suit, il n'est pas trivial de gérer le chemin que l'import reçoit. En fait, il est impossible de remplacer le comportement de l'import dans les dépendances.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getPath() {
        if (Math.random() < 0.5) {
            return "./foo.ts";
        }
        else {
            return "./foo.js";
        }
    }
     
    let myImport = await import(getPath());

    Un autre problème est que (comme cela a été vu plus haut) seuls les chemins relatifs sont réécrits, et ils sont écrits de manière "naïve". Cela signifie que tout chemin qui repose sur la baseUrl et les paths de TypeScript ne sera pas réécrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // tsconfig.json
     
    {
        "compilerOptions": {
            "module": "nodenext",
            // ...
            "paths": {
                "@/*": ["./src/*"]
            }
        }
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Won't be transformed, won't work.
    import * as utilities from "@/utilities.ts";

    Il en va de même pour tout chemin qui pourrait être résolu par les champs exports et imports d'un package.json.

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Won't be transformed, won't work.
    import * as utilities from "#root/utilities.ts";

    Par conséquent, si une présentation de type espace de travail est utilisée avec plusieurs paquets se référençant les uns les autres, il se peut que l'utilisation des exportations conditionnelles avec des conditions personnalisées étendues soit nécessaire pour que cela fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // my-package/package.json
     
    {
        "name": "my-package",
        "exports": {
            ".": {
                "@my-package/development": "./src/index.ts",
                "import": "./lib/index.js"
            },
            "./*": {
                "@my-package/development": "./src/*.ts",
                "import": "./lib/*.js"
            }
        }
    }

    Chaque fois qu'on veut importer les fichiers .ts, on peut l'exécuter avec node --conditions=@my-package/development.

    Notez le « namespace » ou « scope » utilisé pour la condition @my-package/development. Il s'agit d'une solution de fortune pour éviter les conflits avec les dépendances qui pourraient également utiliser la condition development. Si tout le monde livre un développement dans son paquet, alors la résolution peut essayer de se résoudre à un fichier .ts, ce qui ne fonctionnera pas nécessairement.

    Prise en charge de --target es2024 et --lib es2024

    TypeScript 5.7 supporte désormais --target es2024, qui permet aux utilisateurs de cibler les runtimes ECMAScript 2024. Cette cible permet principalement de spécifier la nouvelle --lib es2024 qui contient de nombreuses fonctionnalités pour SharedArrayBuffer et ArrayBuffer, Object.groupBy, Map.groupBy, Promise.withResolvers, et plus encore. Elle déplace également Atomics.waitAsync de --lib es2022 vers --lib es2024.

    Notez que les modifications apportées à SharedArrayBuffer et ArrayBuffer ont entraîné une légère divergence entre ces deux types de tampons. Pour combler le fossé et préserver le type de tampon sous-jacent, tous les TypedArrays (comme Uint8Array et autres) sont désormais également génériques.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> {
        // ...
    }

    Chaque TypedArray contient désormais un paramètre de type nommé TArrayBuffer, bien que ce paramètre de type ait un argument de type par défaut afin que l'on puisse continuer à faire référence à Int32Array sans écrire explicitement Int32Array<ArrayBufferLike>.

    Si des problèmes surviennent dans le cadre de cette mise à jour, il est possible de mettre à jour @types/node.

    Recherche de fichiers de configuration ancestraux pour la propriété du projet

    Lorsqu'un fichier TypeScript est chargé dans un éditeur utilisant TSServer (comme Visual Studio ou VS Code), l'éditeur essaiera de trouver le fichier tsconfig.json pertinent qui « détient » le fichier. Pour ce faire, il remonte l'arbre des répertoires à partir du fichier en cours d'édition, à la recherche de tout fichier nommé tsconfig.json.

    Auparavant, cette recherche s'arrêtait au premier fichier tsconfig.json trouvé ; cependant, on peut imaginer une structure de projet comme la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    project/
    ├── src/
    │   ├── foo.ts
    │   ├── foo-test.ts
    │   ├── tsconfig.json
    │   └── tsconfig.test.json
    └── tsconfig.json

    Ici, l'idée est que src/tsconfig.json est le fichier de configuration « principal » du projet, et src/tsconfig.test.json est un fichier de configuration pour l'exécution des tests.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // src/tsconfig.json
    {
        "compilerOptions": {
            "outDir": "../dist"
        },
        "exclude": ["**/*.test.ts"]
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // src/tsconfig.test.json
    {
        "compilerOptions": {
            "outDir": "../dist/test"
        },
        "include": ["**/*.test.ts"],
        "references": [
            { "path": "./tsconfig.json" }
        ]
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // tsconfig.json
    {
        // This is a "workspace-style" or "solution-style" tsconfig.
        // Instead of specifying any files, it just references all the actual projects.
        "files": [],
        "references": [
            { "path": "./src/tsconfig.json" },
            { "path": "./src/tsconfig.test.json" },
        ]
    }

    Le problème est qu'en éditant foo-test.ts, l'éditeur trouverait project/src/tsconfig.json comme fichier de configuration « propriétaire » - mais ce n'est pas celui que l'on veut ! Si la marche s'arrête à ce point, ce n'est peut-être pas souhaitable. La seule façon d'éviter cela était de renommer src/tsconfig.json en quelque chose comme src/tsconfig.src.json, et alors tous les fichiers seraient dirigés vers le fichier de premier niveau tsconfig.json qui fait référence à tous les projets possibles.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    project/
    ├── src/
    │   ├── foo.ts
    │   ├── foo-test.ts
    │   ├── tsconfig.src.json
    │   └── tsconfig.test.json
    └── tsconfig.json

    Au lieu de forcer les développeurs à le faire, TypeScript 5.7 continue maintenant à remonter l'arbre des répertoires pour trouver d'autres fichiers tsconfig.json appropriés pour les scénarios de l'éditeur. Cela permet une plus grande flexibilité dans l'organisation des projets et la structuration des fichiers de configuration.

    Vérifications plus rapides de la propriété du projet dans les éditeurs pour les projets composites

    Imaginez une grande base de code avec la structure suivante :

    Code : 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
    19
    20
    21
    22
    packages
    ├── graphics/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── sound/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── networking/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    ├── input/
    │   ├── tsconfig.json
    │   └── src/
    │       └── ...
    └── app/
        ├── tsconfig.json
        ├── some-script.js
        └── src/
            └── ...

    Chaque répertoire de packages est un projet TypeScript distinct, et le répertoire app est le projet principal qui dépend de tous les autres projets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // app/tsconfig.json
    {
        "compilerOptions": {
            // ...
        },
        "include": ["src"],
        "references": [
            { "path": "../graphics/tsconfig.json" },
            { "path": "../sound/tsconfig.json" },
            { "path": "../networking/tsconfig.json" },
            { "path": "../input/tsconfig.json" }
        ]
    }

    Remarquez maintenant que le fichier some-script.js se trouve dans le répertoire app. Lorsque l'on ouvre le fichier some-script.js dans l'éditeur, le service de langage TypeScript (qui gère également l'expérience de l'éditeur pour les fichiers JavaScript !) doit déterminer à quel projet appartient le fichier afin d'appliquer les bons paramètres.

    Dans ce cas, le fichier tsconfig.json le plus proche n'inclut pas some-script.js, mais TypeScript demandera « si l'un des projets référencés par app/tsconfig.json inclut some-script.js ». Pour ce faire, TypeScript aurait préalablement chargé chaque projet, un par un, et se serait arrêté dès qu'il aurait trouvé un projet contenant some-script.js. Même si some-script.js n'est pas inclus dans l'ensemble des fichiers de la racine, TypeScript analyserait quand même tous les fichiers d'un projet, car certains des fichiers de la racine peuvent toujours faire référence à some-script.js de manière transitoire.

    Au fil du temps, il a été constaté que ce comportement entraînait des réactions extrêmes et imprévisibles dans les bases de code les plus importantes. Les développeurs ouvraient des fichiers de script égarés et se retrouvaient à attendre que l'ensemble de leur base de code soit ouvert.

    Heureusement, chaque projet qui peut être référencé par un autre projet (hors espace de travail) doit activer un indicateur appelé composite, qui applique une règle selon laquelle tous les fichiers sources d'entrée doivent être connus à l'avance. Ainsi, lors de l'analyse d'un projet composite, TypeScript 5.7 ne vérifiera que si un fichier appartient à l'ensemble de fichiers racine de ce projet. Cela devrait permettre d'éviter ce comportement courant dans le pire des cas.

    Importations JSON validées dans --module nodenext

    Lors de l'importation d'un fichier .json sous --module nodenext, TypeScript appliquera désormais certaines règles pour éviter les erreurs d'exécution.

    Par exemple, un attribut import contenant type : "json" doit être présent pour toute importation de fichier JSON.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import myConfig from "./myConfig.json";
    //                   ~~~~~~~~~~~~~~~~~
    //  error: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'.
     
    import myConfig from "./myConfig.json" with { type: "json" };
    //                                          ^^^^^^^^^^^^^^^^
    //  This is fine because we provided `type: "json"`

    En plus de cette validation, TypeScript ne génère pas d'exportations « nommées », et le contenu d'une importation JSON ne sera accessible que par défaut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //  This is okay:
    import myConfigA from "./myConfig.json" with { type: "json" };
    let version = myConfigA.version;
     
    ///////////
     
    import * as myConfigB from "./myConfig.json" with { type: "json" };
     
    //  This is not:
    let version = myConfig.version;
     
    //  This is okay:
    let version = myConfig.default.version;

    Prise en charge de la mise en cache de la compilation V8 dans Node.js

    Node.js 22 prend en charge une nouvelle API appelée module.enableCompileCache(). Cette API permet au moteur d'exécution de réutiliser une partie du travail d'analyse et de compilation effectué après la première exécution d'un outil.

    TypeScript 5.7 exploite désormais l'API afin de pouvoir commencer à effectuer un travail utile plus tôt. Lors de certains tests, il a été constaté une accélération de 2,5 fois lors de l'exécution de tsc --version.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Benchmark 1: node ./built/local/_tsc.js --version (*without* caching)
      Time (mean ± σ):     122.2 ms ±   1.5 ms    [User: 101.7 ms, System: 13.0 ms]
      Range (min … max):   119.3 ms … 132.3 ms    200 runs
     
    Benchmark 2: node ./built/local/tsc.js --version  (*with* caching)
      Time (mean ± σ):      48.4 ms ±   1.0 ms    [User: 34.0 ms, System: 11.1 ms]
      Range (min … max):    45.7 ms …  52.8 ms    200 runs
     
    Summary
      node ./built/local/tsc.js --version ran
        2.52 ± 0.06 times faster than node ./built/local/_tsc.js --version

    Modifications notables du comportement

    Vous trouverez dans cette section un ensemble de changements notables qu'il convient de reconnaître et de comprendre dans le cadre d'une mise à jour. Elle met parfois en évidence des dépréciations, des suppressions et de nouvelles restrictions. Elle peut également contenir des corrections de bogues qui sont des améliorations fonctionnelles, mais qui peuvent également affecter une version existante en introduisant de nouvelles erreurs.

    Quelles sont les prochaines étapes ?

    À ce stade, l'équipe TypeScript prévoit très peu de changements pour TypeScript 5.7 en dehors des corrections de bogues critiques pour le compilateur et des corrections de bogues mineurs pour le service de langage. Dans les prochaines semaines, la première version stable de TypeScript 5.7 sera publiée. Gardez un œil sur le plan d'itération pour connaître les dates de publication.

    Citation Envoyé par Microsoft
    Nous nous concentrons principalement sur le développement de TypeScript 5.7, et nous aurons le plan d'itération disponible dans les prochains jours (y compris les dates de sortie prévues). De plus, nous facilitons l'utilisation des nightly builds de TypeScript sur npm, et il existe une extension pour utiliser ces nightly releases dans Visual Studio Code.
    Source : Microsoft

    Et vous ?

    Quel est votre avis sur le sujet ?
    Que pensez-vous des fonctionnalités proposées par cette version de TypeScript ?

    Voir aussi :

    Microsoft annonce la disponibilité de TypeScript 5.7 Beta, apportant des améliorations à la vérification des variables jamais initialisées et une vérification plus rapide de la propriété d'un projet

    Microsoft annonce la disponibilité de TypeScript 5.6, apportant des améliorations à la vérification vraie et nulle non autorisée ainsi que des méthodes d'aide pour les itérateurs
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Microsoft annonce la disponibilité de TypeScript 5.5 Beta
    Par Jade Emy dans le forum TypeScript
    Réponses: 3
    Dernier message: 21/06/2024, 10h35
  2. Microsoft annonce la disponibilité de TypeScript 5.4 Beta
    Par Jade Emy dans le forum TypeScript
    Réponses: 2
    Dernier message: 07/03/2024, 12h53
  3. Microsoft annonce la disponibilité de TypeScript 5.2 Beta.
    Par Nancy Rey dans le forum TypeScript
    Réponses: 2
    Dernier message: 10/08/2023, 11h46
  4. Microsoft annonce la disponibilité de TypeScript 2.4
    Par Stéphane le calme dans le forum TypeScript
    Réponses: 1
    Dernier message: 28/06/2017, 08h38
  5. Réponses: 0
    Dernier message: 23/02/2017, 13h12

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