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 4.9


Sujet :

TypeScript

  1. #1
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Mai 2019
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2019
    Messages : 1 986
    Points : 38 590
    Points
    38 590
    Par défaut Microsoft annonce la disponibilité de TypeScript 4.9
    TypeScript 4.9 Beta est disponible et apporte la restriction des propriétés non listées avec l'opérateur in
    ainsi que la vérification de l'égalité sur NaN

    TypeScript, c'est un langage qui s'appuie sur JavaScript et ajoute une syntaxe pour les types. Dans un article publié sur son blog ce 23 septembre, Microsoft a annoncé la version bêta de TypeScript 4.9.

    Les types aident à décrire les types de valeurs avec lesquelles vous travaillez et les types de fonctions que vous appelez. TypeScript peut utiliser ces informations pour vous aider à éviter les erreurs telles que les fautes de frappe, les arguments manquants ou l'oubli de vérifier null et undefined ! Mais cette vérification de type n'est pas la seule chose que fait TypeScript - il utilise les informations de ces types pour vous offrir une expérience d'édition, alimentant des éléments tels que la complétion de code, la définition, le changement de nom, etc.

    Nom : typescriptB.png
Affichages : 21289
Taille : 44,5 Ko

    Voici, ci-dessous, les nouveautés qu’apporte TypeScript 4.9 :

    L'opérateur satisfies

    Les développeurs TypeScript sont souvent confrontés à un dilemme : nous voulons nous assurer qu'une expression correspond à un certain type, mais nous voulons également conserver le type le plus spécifique de cette expression à des fins d'inférence. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Each property can be a string or an RGB tuple.
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ^^^^ sacré bleu - we've made a typo!
    };
     
    // We want to be able to use array methods on 'red'...
    const redComponent = palette.red.at(0);
     
    // or string methods on 'green'...
    const greenNormalized = palette.green.toUpperCase();

    Remarquez qu'il est écrit bleu, alors qu'on aurait probablement dû écrire blue. La faute de frappe de bleu peut être corrigée en utilisant une annotation de type sur palette, mais des informations seraient perdues sur chaque propriété.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Colors = "red" | "green" | "blue";
     
    type RGB = [red: number, green: number, blue: number];
     
    const palette: Record<Colors, string | RGB> = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ~~~~ The typo is now correctly detected
    };
     
    // But we now have an undesirable error here - 'palette.red' "could" be a string.
    const redComponent = palette.red.at(0);

    Le nouvel opérateur satisfies permet de valider que le type d'une expression correspond à un certain type, sans modifier le type résultant de cette expression. Par exemple, nous pourrions utiliser satisfies pour valider que toutes les propriétés de palette sont compatibles avec string | number[] :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type Colors = "red" | "green" | "blue";
     
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ~~~~ The typo is now caught!
    } satisfies Record<Colors, string | RGB>;
     
    // Both of these methods are still accessible!
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    satisfies peut être utilisé pour détecter de nombreuses erreurs possibles. Par exemple, nous pouvons nous assurer qu'un objet possède toutes les clés d'un certain type, mais pas plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Colors = "red" | "green" | "blue";
     
    // Ensure that we have exactly the keys from 'Colors'.
    const favoriteColors = {
        "red": "yes",
        "green": false,
        "blue": "kinda",
        "platypus": false
    //  ~~~~~~~~~~ error - "platypus" was never listed in 'Colors'.
    } satisfies Record<Colors, unknown>;
     
    // All the information about the 'red', 'green', and 'blue' properties are retained.
    const g: boolean = favoriteColors.green;

    Peut-être que nous ne nous soucions pas de savoir si les noms des propriétés correspondent d'une manière ou d'une autre, mais que nous nous soucions des types de chaque propriété. Dans ce cas, nous pouvons également nous assurer que toutes les valeurs des propriétés d'un objet sont conformes à un certain type.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        blue: [0, 0]
        //    ~~~~~~ error!
    } satisfies Record<string, string | RGB>;
     
    // Information about each property is still maintained.
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    Restriction des propriétés non listées avec l'opérateur in

    En tant que développeurs, nous devons souvent traiter des valeurs qui ne sont pas entièrement connues au moment de l'exécution. En fait, il arrive souvent que nous ne sachions pas si des propriétés existent, que nous obtenions une réponse d'un serveur ou que nous lisions un fichier de configuration. L'opérateur in de JavaScript peut vérifier si une propriété existe sur un objet. Auparavant, TypeScript nous permettait d'éliminer tous les types qui ne listaient pas explicitement une propriété.

    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
    interface RGB {
        red: number;
        green: number;
        blue: number;
    }
     
    interface HSV {
        hue: number;
        saturation: number;
        value: number;
    }
     
    function setColor(color: RGB | HSV) {
        if ("hue" in color) {
            // 'color' now has the type HSV
        }
        // ...
    }

    Ici, le type RGB n'a pas listé la teinte et a été restreint, nous laissant avec le type HSV. Mais qu'en est-il des exemples où aucun type ne mentionne une propriété donnée ? Dans ces cas-là, le langage ne nous a pas beaucoup aidés. Prenons l'exemple suivant en JavaScript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function tryGetPackageName(context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    La réécriture en TypeScript canonique serait juste une question de définition et d'utilisation d'un type pour le contexte ; cependant, le choix d'un type fiable comme unknown pour la propriété packageJSON causerait des problèmes dans les anciennes versions de TypeScript.

    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
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
            //                                              ~~~~
            // error! Property 'name' does not exist on type 'object.
                return packageJSON.name;
            //                     ~~~~
            // error! Property 'name' does not exist on type 'object.
            }
        }
     
        return undefined;
    }

    En effet, alors que le type de packageJSON est passé d'inconnu à objet, l'opérateur in est strictement limité aux types qui définissent réellement la propriété vérifiée. Par conséquent, le type de packageJSON est resté objet. TypeScript 4.9 rend l'opérateur in un peu plus puissant lorsqu'il s'agit de restreindre les types qui ne répertorient pas du tout la propriété. Au lieu de les laisser tels quels, le langage intersectera leurs types avec Record<"property-key-being-checked", unknown>.

    Ainsi, dans notre exemple, le type de packageJSON sera réduit d'inconnu à objet Record<"name", unknown>. Cela nous permet d'accéder directement à packageJSON.name et de le réduire indépendamment.

    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
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context): string | undefined {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                // Just works!
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    TypeScript 4.9 renforce également quelques contrôles sur la façon dont in est utilisé, en s'assurant que le côté gauche est assignable au type string | number | symbol, et que le côté droit est assignable à object. Cela permet de vérifier que nous utilisons des clés de propriété valides et que nous ne vérifions pas accidentellement des primitives.

    Vérification de l'égalité sur NaN

    Une des principales difficultés rencontrées par les développeurs JavaScript est la vérification de la valeur NaN à l'aide des opérateurs d'égalité intégrés. Pour rappel, NaN est une valeur numérique spéciale qui signifie Not a Number (pas un nombre). Rien n'est jamais égal à NaN - même NaN !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN == 0)  // false
    console.log(NaN === 0) // false
     
    console.log(NaN == NaN)  // false
    console.log(NaN === NaN) // false

    Mais au moins symétriquement, tout est toujours non égal à NaN.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN != 0)  // true
    console.log(NaN !== 0) // true
     
    console.log(NaN != NaN)  // true
    console.log(NaN !== NaN) // true

    Techniquement, ce n'est pas un problème spécifique à JavaScript, puisque n'importe quel langage qui contient des flottants IEEE-754 a le même comportement ; mais le principal type numérique de JavaScript est un nombre à virgule flottante, et l'analyse des nombres en JavaScript peut souvent aboutir à NaN. A son tour, la vérification contre les NaN finit par être assez commune, et la manière correcte de le faire est d'utiliser Number.isNaN - mais comme nous l'avons mentionné, beaucoup de gens finissent accidentellement par vérifier avec someValue === NaN à la place.

    TypeScript se trompe maintenant sur les comparaisons directes avec NaN, et suggère d'utiliser une variation de Number.isNaN à la place.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function validate(someValue: number) {
        return someValue !== NaN;
        //     ~~~~~~~~~~~~~~~~~
        // error: This condition will always return 'true'.
        //        Did you mean '!Number.isNaN(someValue)'?
    }

    La surveillance des fichiers utilise désormais les événements du système de fichiers

    Dans les versions précédentes, TypeScript s'appuyait fortement sur l'interrogation pour surveiller les fichiers individuels. L'utilisation d'une stratégie d'interrogation signifiait la vérification périodique de l'état d'un fichier pour les mises à jour. Sur Node.js, fs.watchFile est le moyen intégré d'obtenir une surveillance de fichier par sondage. Bien que l'interrogation ait tendance à être plus prévisible sur les plateformes et les systèmes de fichiers, cela signifie que votre CPU doit être interrompu périodiquement et vérifier les mises à jour du fichier, même si rien n'a changé. Pour quelques dizaines de fichiers, cela peut ne pas être perceptible, mais sur un projet plus important avec beaucoup de fichiers - ou beaucoup de fichiers dans les node_modules - cela peut devenir un monstre de ressources.

    De manière générale, une meilleure approche consiste à utiliser les événements du système de fichiers. Au lieu de sonder, nous pouvons annoncer que nous sommes intéressés par les mises à jour de fichiers spécifiques et fournir un rappel lorsque ces fichiers sont effectivement modifiés. La plupart des plateformes modernes utilisées fournissent des facilités et des APIs comme CreateIoCompletionPort, kqueue, epoll et inotify. Node.js les rend abstraites en fournissant fs.watch. Les événements du système de fichiers fonctionnent généralement très bien, mais il y a beaucoup d'inconvénients à les utiliser et, par conséquent, à utiliser l'API fs.watch.

    Un observateur doit faire attention à prendre en compte la surveillance des inodes, l'indisponibilité de certains systèmes de fichiers (par exemple les systèmes de fichiers en réseau), si la surveillance récursive des fichiers est disponible, si les renommages de répertoires déclenchent des événements, et même l'épuisement des observateurs de fichiers ! En d'autres termes, ce n'est pas tout à fait un repas gratuit, surtout si vous recherchez quelque chose de multiplateforme.

    Par conséquent, Microsoft a choisi par défaut le plus petit dénominateur commun : l'interrogation. Pas toujours, mais la plupart du temps. Au fil du temps, Microsoft a fourni les moyens de choisir d'autres stratégies de surveillance des fichiers. Cela a permis d'obtenir un retour d'information et de renforcer l'implémentation de file-watching contre la plupart de ces problèmes spécifiques à la plateforme. Comme TypeScript a dû s'adapter à des bases de code plus importantes, et s'est amélioré dans ce domaine, nous avons estimé que le passage aux événements du système de fichiers par défaut serait un investissement rentable.

    Dans TypeScript 4.9, la surveillance des fichiers est alimentée par les événements du système de fichiers par défaut, ne revenant à l'interrogation que si nous ne parvenons pas à mettre en place des surveillances basées sur des événements. Pour la plupart des développeurs, cela devrait fournir une expérience beaucoup moins gourmande en ressources lors de l'exécution en mode --watch, ou lors de l'exécution avec un éditeur alimenté par TypeScript comme Visual Studio ou VS Code.

    Le mode de fonctionnement de la surveillance des fichiers peut toujours être configuré par le biais de variables d'environnement et de watchOptions - et certains éditeurs comme VS Code peuvent prendre en charge les watchOptions de manière indépendante. Les développeurs utilisant des configurations plus exotiques où le code source réside sur un système de fichiers en réseau (comme NFS et SMB) peuvent avoir besoin de revenir à l'ancien comportement ; bien que si un serveur a une puissance de traitement raisonnable, il pourrait être préférable d'activer SSH et d'exécuter TypeScript à distance afin qu'il ait un accès direct aux fichiers locaux. VS Code dispose de nombreuses extensions à distance pour faciliter cette tâche.

    Corrections et modifications de rupture

    Mises à jour de lib.d.ts

    Alors que TypeScript s'efforce d'éviter les ruptures majeures, même les petits changements dans les bibliothèques intégrées peuvent causer des problèmes. Nous ne nous attendons pas à des ruptures majeures à la suite des mises à jour de DOM et lib.d.ts, mais il peut y avoir quelques petites ruptures.

    Meilleurs types pour Promise.resolve

    Promise.resolve utilise désormais le type Awaited pour déballer les types de type Promise qui lui sont transmis. Cela signifie qu'il renvoie plus souvent le bon type de Promise, mais ce type amélioré peut casser le code existant s'il s'attendait à un type quelconque ou inconnu au lieu d'une Promise.

    JavaScript Emit n'élide plus les importations

    Lorsque TypeScript a commencé à supporter la vérification de type et la compilation pour JavaScript, il a accidentellement supporté une fonctionnalité appelée import elision. En bref, si une importation n'est pas utilisée comme une valeur, ou si le compilateur peut détecter que l'importation ne se réfère pas à une valeur au moment de l'exécution, le compilateur laissera tomber l'importation pendant l'émission.

    Ce comportement était discutable, en particulier la détection du fait que l'importation ne se réfère pas à une valeur, car cela signifie que TypeScript doit faire confiance aux fichiers de déclaration parfois imprécis. En contrepartie, TypeScript préserve désormais les importations dans les fichiers JavaScript.

    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
    // Input:
    import { someValue, SomeClass } from "some-module";
     
    /** @type {SomeClass} */
    let val = someValue;
     
    // Previous Output:
    import { someValue } from "some-module";
     
    /** @type {SomeClass} */
    let val = someValue;
     
    // Current Output:
    import { someValue, SomeClass } from "some-module";
     
    /** @type {SomeClass} */
    let val = someValue;

    exports est prioritaire sur typesVersions

    Auparavant, TypeScript donnait incorrectement la priorité au champ typesVersions sur le champ exports lors de la résolution d'un package.json sous --moduleResolution node16. Si ce changement a un impact sur la bibliothèque, vous devrez peut-être ajouter des sélecteurs de version types@ dans le champ exports du package.json.

    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
      {
          "type": "module",
          "main": "./dist/main.js"
          "typesVersions": {
              "<4.8": { ".": ["4.8-types/main.d.ts"] },
              "*": { ".": ["modern-types/main.d.ts"] }
          },
          "exports": {
              ".": {
    +             "types@<4.8": "4.8-types/main.d.ts",
    +             "types": "modern-types/main.d.ts",
                  "import": "./dist/main.js"
              }
          }
      }

    Substitute remplacé par constraint sur les SubstitutionTypes

    Dans le cadre d'une optimisation des types de substitution, les objets SubstitutionType ne contiennent plus la propriété substitute représentant la substitution effective (généralement une intersection du type de base et de la contrainte implicite) - à la place, ils contiennent uniquement la propriété constraint.

    Source : Microsoft

    Voir aussi :

    La version bêta de TypeScript 4.2 est disponible avec le type tuple plus amélioré et une préservation plus intelligente des alias de type

    Microsoft publie TypeScript 4.2 avec la prise en charge de Abstract Constructor Types et des contrôles plus stricts pour l'opérateur in

    Prisma : un ORM de nouvelle génération pour Node.js et TypeScript, pour concurrencer TypeORM et Sequelize et devenir la norme de l'industrie

    Comment un développeur JavaScript anti-TypeScript est devenu un fan de TypeScript ? Voici les raisons de Chirag Swadia, un développeur JavaScript reconverti en développeur TypeScript

  2. #2
    Chroniqueur Actualités
    Avatar de Bruno
    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Mai 2019
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Rédacteur technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2019
    Messages : 1 986
    Points : 38 590
    Points
    38 590
    Par défaut TypeScript 4.9 RC est disponible et apporte les accesseurs automatiques dans les classes
    TypeScript 4.9 RC est disponible et apporte les accesseurs automatiques dans les classes,
    La surveillance des fichiers utilise maintenant les événements du système de fichiers

    Depuis la publication de la version bêta le 25 septembre, TypeScript prend désormais en charge les accesseurs automatiques dans les classes. Dans les versions antérieures, TypeScript s'appuyait fortement sur l'interrogation pour suivre les fichiers individuels. Avec la release candidate (RC) de TypeScript 4.9, la surveillance des fichiers utilise maintenant les événements du système de fichiers et la façon dont TypeScript préserve les informations sur un type dans la branche vraie d'un type conditionnel a été optimisée. D'ici la version stable de TypeScript 4.9, Microsoft n'attend aucun autre changement en dehors des corrections de bogues critiques.

    Nom : typescriptB2.png
Affichages : 9442
Taille : 4,6 Ko

    L'opérateur satisfies

    Les développeurs TypeScript sont souvent confrontés à un dilemme : ils veulent s'assurer qu'une expression correspond à un certain type, mais ils voulent également conserver le type le plus spécifique de cette expression à des fins d'inférence. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Each property can be a string or an RGB tuple.
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ^^^^ sacrebleu - we've made a typo!
    };
     
    // We want to be able to use array methods on 'red'...
    const redComponent = palette.red.at(0);
     
    // or string methods on 'green'...
    const greenNormalized = palette.green.toUpperCase();

    Remarquez que Microsoft écrit bleu, alors que nous elle aurait probablement dû écrire blue. Nous pourrions essayer de corriger la faute de frappe de bleu en utilisant une annotation de type sur palette, mais nous perdrions les informations sur chaque propriété.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Colors = "red" | "green" | "blue";
     
    type RGB = [red: number, green: number, blue: number];
     
    const palette: Record<Colors, string | RGB> = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ~~~~ The typo is now correctly detected
    };
     
    // But we now have an undesirable error here - 'palette.red' "could" be a string.
    const redComponent = palette.red.at(0);

    Le nouvel opérateur satisfies nous permet de valider que le type d'une expression correspond à un certain type, sans modifier le type résultant de cette expression. Par exemple, nous pourrions utiliser satisfies pour valider que toutes les propriétés de palette sont compatibles avec string | number[] :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type Colors = "red" | "green" | "blue";
     
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ~~~~ The typo is now caught!
    } satisfies Record<Colors, string | RGB>;
     
    // Both of these methods are still accessible!
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    satisfies peut être utilisé pour visualiser de nombreuses erreurs possibles. Par exemple, nous pouvons nous assurer qu'un objet possède toutes les clés d'un certain type, mais pas plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Colors = "red" | "green" | "blue";
     
    // Ensure that we have exactly the keys from 'Colors'.
    const favoriteColors = {
        "red": "yes",
        "green": false,
        "blue": "kinda",
        "platypus": false
    //  ~~~~~~~~~~ error - "platypus" was never listed in 'Colors'.
    } satisfies Record<Colors, unknown>;
     
    // All the information about the 'red', 'green', and 'blue' properties are retained.
    const g: boolean = favoriteColors.green;

    Peut-être que nous ne nous soucions pas de savoir si les noms des propriétés correspondent d'une manière ou d'une autre, mais que nous nous intéressons aux types de chaque propriété. Dans ce cas, nous pouvons également nous assurer que toutes les valeurs des propriétés d'un objet sont conformes à un certain type.

    [CODE]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        blue: [0, 0]
        //    ~~~~~~ error!
    } satisfies Record<string, string | RGB>;
     
    // Information about each property is still maintained.
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    Restriction des propriétés non listées avec l'opérateur in

    En tant que développeurs, nous devons souvent traiter des valeurs qui ne sont pas entièrement connues au moment de l'exécution. En fait, il arrive souvent que nous ne sachions pas si des propriétés existent, que nous obtenions une réponse d'un serveur ou que nous lisions un fichier de configuration. L'opérateur in de JavaScript peut vérifier si une propriété existe sur un objet.

    Auparavant, TypeScript nous permettait d'éliminer tous les types qui ne listaient pas explicitement une propriété.


    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
    interface RGB {
        red: number;
        green: number;
        blue: number;
    }
     
    interface HSV {
        hue: number;
        saturation: number;
        value: number;
    }
     
    function setColor(color: RGB | HSV) {
        if ("hue" in color) {
            // 'color' now has the type HSV
        }
        // ...
    }
    Ici, le type RGB n'a pas listé hueet a été restreint, nous laissant avec le type HSV. Mais qu'en est-il des exemples où aucun type ne mentionne une propriété donnée ? Dans ces cas-là, le langage ne nous a pas beaucoup aidés. Prenons l'exemple suivant en JavaScript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function tryGetPackageName(context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    La réécriture en TypeScript classique serait juste une question de définition et d'utilisation d'un type pour le contexte ; cependant, le choix d'un type sûr comme [C]unknown[C] pour la propriété packageJSON causerait des problèmes dans les anciennes versions de TypeScript.

    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
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
            //                                              ~~~~
            // error! Property 'name' does not exist on type 'object.
                return packageJSON.name;
            //                     ~~~~
            // error! Property 'name' does not exist on type 'object.
            }
        }
     
        return undefined;
    }

    En effet, alors que le type de packageJSON est passé d'inconnu à objet, l'opérateur in est strictement limité aux types qui définissent réellement la propriété vérifiée. Par conséquent, le type de packageJSON est resté objet.

    TypeScript 4.9 rend l'opérateur in un peu plus puissant lorsqu'il s'agit de restreindre les types qui ne répertorient pas du tout la propriété. Au lieu de les laisser tels quels, le langage intersectera leurs types avec Record<"property-key-being-checked", unknown>. Ainsi, dans notre exemple, le type de packageJSON sera réduit de unknown à objet à objet & Record<"name", inconnu>. Cela nous permet d'accéder directement à packageJSON.name et de le réduire indépendamment.

    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
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context): string | undefined {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                // Just works!
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    TypeScript 4.9 renforce également quelques contrôles sur la façon dont in est utilisé, en s'assurant que le côté gauche est assignable au type string | number | symbol, et que le côté droit est assignable à object. Cela permet de vérifier que nous utilisons des clés de propriété valides et que nous ne vérifions pas accidentellement des primitives.

    Accesseurs automatiques dans les classes

    TypeScript 4.9 prend en charge une fonctionnalité à venir dans ECMAScript appelée auto-accesseurs. Les auto-accesseurs sont déclarés comme les propriétés des classes, sauf qu'ils sont déclarés avec le mot-clé accessor.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Person {
        accessor name: string;
     
        constructor(name: string) {
            this.name = name;
        }

    En dessous, ces auto-accesseurs se "désagrègent" en un accesseur get et set avec une propriété privée inaccessible.

    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
    class Person {
        #__name: string;
     
        get name() {
            return this.#__name;
        }
        set name(value: string) {
            this.#__name = name;
        }
     
        constructor(name: string) {
            this.name = name;
        }
    }
    }

    Contrôles d'égalité sur NaN

    L'une des principales difficultés rencontrées par les développeurs JavaScript est la vérification de la valeur NaN à l'aide des opérateurs d'égalité intégrés. Pour rappel, NaN est une valeur numérique spéciale qui signifie "Not a Number" (pas un nombre). Rien n'est jamais égal à NaN - même NaN !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN == 0)  // false
    console.log(NaN === 0) // false
     
    console.log(NaN == NaN)  // false
    console.log(NaN === NaN) // false

    Mais au moins symétriquement, tout est toujours non égal à NaN.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN != 0)  // true
    console.log(NaN !== 0) // true
     
    console.log(NaN != NaN)  // true
    console.log(NaN !== NaN) // true

    Techniquement, ce n'est pas un problème spécifique à JavaScript, puisque n'importe quel langage qui contient des flottants IEEE-754 a le même comportement ; mais le principal type numérique de JavaScript est un nombre à virgule flottante, et l'analyse des nombres en JavaScript peut souvent aboutir à NaN. A son tour, la vérification contre les NaN finit par être assez commune, et la manière correcte de le faire est d'utiliser Number.isNaN - mais comme nous l'avons mentionné, beaucoup de gens finissent par vérifier avec someValue === NaN à la place.

    TypeScript se trompe maintenant sur les comparaisons directes avec NaN, et suggère d'utiliser une variation de Number.isNaN à la place.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function validate(someValue: number) {
        return someValue !== NaN;
        //     ~~~~~~~~~~~~~~~~~
        // error: This condition will always return 'true'.
        //        Did you mean '!Number.isNaN(someValue)'?
    }

    Ce changement devrait aider à détecter les erreurs de débutants, de la même manière que TypeScript émet actuellement des erreurs sur les comparaisons avec les littéraux d'objets et de tableaux.

    La surveillance des fichiers utilise maintenant les événements du système de fichiers

    Dans les versions antérieures, TypeScript s'appuyait fortement sur l'interrogation pour suivre les fichiers individuels. L'utilisation d'une stratégie d'interrogation signifiait la vérification périodique de l'état d'un fichier pour les mises à jour. Sur Node.js, fs.watchFile est le moyen intégré d'obtenir un observateur de fichiers par échantillonnage. Bien que l'interrogation ait tendance à être plus prévisible sur les plateformes et les systèmes de fichiers, cela signifie que le CPU doit être interrompu périodiquement et vérifier les mises à jour du fichier, même si rien n'a changé. Pour quelques dizaines de fichiers, cela peut ne pas être perceptible, mais sur un projet plus important avec beaucoup de fichiers - ou beaucoup de fichiers dans les node_modules - cela peut devenir un monstre de ressources.

    La plupart des plateformes modernes utilisées fournissent des facilités et des APIs comme CreateIoCompletionPort, kqueue, epoll et inotify. Node.js fait abstraction de tout cela en fournissant fs.watch. Les événements du système de fichiers fonctionnent généralement très bien, mais il y a beaucoup d'inconvénients à les utiliser et, par conséquent, à utiliser l'API fs.watch. Un observateur doit faire attention à prendre en compte la surveillance des inodes, l'indisponibilité de certains systèmes de fichiers (par exemple les systèmes de fichiers en réseau), si la surveillance récursive des fichiers est disponible, si les renommages de répertoires déclenchent des événements, et même l'épuisement des observateurs de fichiers ! En d'autres termes, ce n'est pas tout à fait un repas gratuit, surtout si vous recherchez quelque chose de multiplateforme.

    Par conséquent, Microsoft a choisi par défaut le plus petit dénominateur commun : l'interrogation. Pas toujours, mais la plupart du temps.

    Au fil du temps, Microsoft a fourni les moyens de choisir d'autres stratégies de surveillance des fichiers. « Cela nous a permis d'obtenir un retour d'information et de renforcer notre implémentation de file-watching contre la plupart de ces problèmes spécifiques à la plateforme », déclare l'équipe TypeScript. Comme TypeScript a dû s'adapter à des bases de code plus importantes, et s'est amélioré dans ce domaine, nous avons estimé que le passage aux événements du système de fichiers par défaut serait un investissement rentable.

    Dans TypeScript 4.9, la surveillance des fichiers est alimentée par les événements du système de fichiers par défaut, ne revenant à l'interrogation que si Microsoft ne parvenons pas à mettre en place des surveillances basées sur des événements. Pour la plupart des développeurs, cela devrait fournir une expérience beaucoup moins gourmande en ressources lors de l'exécution en mode --watch, ou lors de l'exécution avec un éditeur alimenté par TypeScript comme Visual Studio ou VS Code.

    La façon dont la surveillance des fichiers fonctionne peut toujours être configurée par le biais de variables d'environnement et d'options de surveillance, et certains éditeurs comme VS Code peuvent prendre en charge les options de surveillance de façon indépendante. Les développeurs utilisant des configurations plus exotiques où le code source réside sur un système de fichiers en réseau (comme NFS et SMB) peuvent avoir besoin de revenir à l'ancien comportement ; bien que si un serveur a une puissance de traitement raisonnable, il pourrait être préférable d'activer SSH et d'exécuter TypeScript à distance afin qu'il ait un accès direct aux fichiers locaux. VS Code dispose de nombreuses extensions à distance pour faciliter cette opération.

    Commandes "Remove Unused Imports" et "Sort Imports" pour les éditeurs

    Auparavant, TypeScript ne prenait en charge que deux commandes d'éditeur pour gérer les importations. Pour nos exemples, prenons le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import { Zebra, Moose, HoneyBadger } from "./zoo";
    import { foo, bar } from "./helper";
     
    let x: Moose | HoneyBadger = foo();
    La première s'appelle "Organize Imports" et supprime les importations inutilisées, puis trie celles qui restent. Il réécrit le fichier pour qu'il ressemble à celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import { foo } from "./helper";
    import { HoneyBadger, Moose } from "./zoo";
     
    let x: Moose | HoneyBadger = foo();
    Dans TypeScript 4.3, nous Microsoft a introduit une commande appelée "Sort Imports" qui ne fait que trier les importations dans le fichier, mais ne les supprime pas - et réécrit le fichier comme ceci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import { bar, foo } from "./helper";
    import { HoneyBadger, Moose, Zebra } from "./zoo";
     
    let x: Moose | HoneyBadger = foo();
    L'inconvénient de "Sort Imports" était que dans Visual Studio Code, cette fonctionnalité n'était disponible qu'en tant que commande on-save - et non en tant que commande déclenchable manuellement.

    TypeScript 4.9 ajoute l'autre moitié, et fournit maintenant "Remove Unused Imports". TypeScript va maintenant supprimer les noms d'importation inutilisés et les déclarations, mais autrement laissera l'ordre relatif seul.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import { Moose, HoneyBadger } from "./zoo";
    import { foo } from "./helper";
     
    let x: Moose | HoneyBadger = foo();

    Améliorations des performances

    TypeScript a quelques petites, mais notables, améliorations de performance

    Tout d'abord, la fonction forEachChild de TypeScript a été réécrite pour utiliser une consultation de table de fonctions au lieu d'une instruction switch sur tous les nœuds syntaxiques. forEachChild est un cheval de bataille pour traverser les nœuds syntaxiques dans le compilateur, et est fortement utilisé dans l'étape de liaison de notre compilateur, avec des parties du service de langue. Le remaniement de forEachChild a permis de réduire jusqu'à 20 % le temps passé dans notre phase de liaison et dans les opérations du service linguistique.

    Après avoir découvert ce gain de performance pour forEachChild, nous l'avons essayé sur visitEachChild, une fonction que nous utilisons pour transformer les nœuds dans le compilateur et le service de langue. La même refactorisation a permis de réduire jusqu'à 3 % le temps passé à générer les résultats du projet. L'exploration initiale de forEachChild a été inspirée par un article de blog d'Artemis Everfree.Enfin, la façon dont TypeScript préserve les informations sur un type dans la branche vraie d'un type conditionnel a été optimisée. Dans un type comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    interface Zoo<T extends Animal> {
        // ...
    }
     
    type MakeZoo<A> = A extends Animal ? Zoo<A> : never;

    TypeScript doit « se souvenir » que A doit également être un animal lorsqu'il vérifie si Zoo<A> est valide. Cela se fait essentiellement en créant un type spécial qui contient l'intersection de A avec Animal ; cependant, TypeScript le faisait auparavant de manière empressée, ce qui n'est pas toujours nécessaire. En outre, un code défectueux dans le vérificateur de type a empêché ces types spéciaux d'être simplifiés.

    TypeScript reporte maintenant l'intersection de ces types jusqu'à ce que cela soit nécessaire. Pour les bases de code avec une utilisation intensive des types conditionnels, vous pourriez assister à des accélérations significatives avec TypeScript, mais dans notre suite de tests de performance, nous avons vu une réduction plus modeste de 3 % du temps de vérification de type.

    Source : Microsoft

    Et vous ?

    Que pensez-vous de TypeScript ?

    Avez-vous déjà utilisé TypeScript ? Pour des projets personnels ou en entreprise ?

    Si vous ne l'avez pas encore utilisé, prévoyez-vous de le faire ? Pourquoi ?

    Quelles améliorations vous intéressent le plus ?

    Voir aussi :

    TypeScript a 10 ans ! Joyeux anniversaire. À cette occasion, Microsoft fait le point. L'entreprise revient sur les doutes des premiers jours ainsi que sur l'évolution du langage

    TypeScript 4.8 bêta apporte des améliorations de performances à --watch et --build, mais empêche l'importation/l'exportation des types dans les fichiers JavaScript

    TypeScript 4.8 RC permet d'exclure des fichiers spécifiques des importations automatiques et améliore l'inférence à partir de modèles de liaison

    TypeScript 4.9 Beta est disponible et apporte la restriction des propriétés non listées avec l'opérateur in, ainsi que la vérification de l'égalité sur NaN

  3. #3
    Chroniqueur Actualités

    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2014
    Messages
    1 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 1 089
    Points : 26 557
    Points
    26 557
    Par défaut Microsoft annonce la disponibilité de TypeScript 4.9
    Microsoft annonce la disponibilité de TypeScript 4.9
    qui se dote du nouvel opérateur « satisfies », améliore l’opérateur « in » et prend en charge déjà les accesseurs automatiques de ECMAScript

    L’équipe de TypeScript vient d’annoncer la disponibilité de la version finale de TypeScript 4.9. Pour cette dernière version, de nombreuses améliorations appréciables sont au rendez-vous. Il s'agit entre autres de la prise en charge d’une fonctionnalité à venir dans ECMAScript nommée « auto-accessors », le renforcement des capacités de l’opérateur « in », l’ajout d’un nouvel opérateur nommé « satifies », et l’introduction de la commande « Remove Unused Imports », pour ne citer que celles-là.

    L’opérateur satifies

    Le nouvel opérateur satifies permet de valider que le type d’une expression correspond à un certain type sans changer le type résultant de cette expression. À titre d’exemple, on pourrait utiliser satifies pour valider que toutes les propriétés de palette sont compatibles avec string | number[]:

    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
    type Colors = "red" | "green" | "blue";
     
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        bleu: [0, 0, 255]
    //  ~~~~ The typo is now caught!
    } satisfies Record<Colors, string | RGB>;
     
    // Both of these methods are still accessible!
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    L’opérateur satifies peut être utilisé pour détecter de nombreuses erreurs possibles. Par exemple, pour s’assurer qu’un objet possède toutes les clés d’un certain type, mais pas plus :

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type Colors = "red" | "green" | "blue";
     
    // Ensure that we have exactly the keys from 'Colors'.
    const favoriteColors = {
        "red": "yes",
        "green": false,
        "blue": "kinda",
        "platypus": false
    //  ~~~~~~~~~~ error - "platypus" was never listed in 'Colors'.
    } satisfies Record<Colors, unknown>;
     
    // All the information about the 'red', 'green', and 'blue' properties are retained.
    const g: boolean = favoriteColors.green;

    Peut-être que cela ne nous intéresse pas de savoir si les noms de propriété correspondent d’une manière ou d’une autre, mais les types de chaque propriété sont assez importants pour effectuer des vérifications de type. Dans ce cas, nous pouvons également nous assurer que toutes les valeurs de propriété d’un objet sont conformes à un certain type.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type RGB = [red: number, green: number, blue: number];
     
    const palette = {
        red: [255, 0, 0],
        green: "#00ff00",
        blue: [0, 0]
        //    ~~~~~~ error!
    } satisfies Record<string, string | RGB>;
     
    // Information about each property is still maintained.
    const redComponent = palette.red.at(0);
    const greenNormalized = palette.green.toUpperCase();

    Limitation des propriétés non répertoriées avec l’opérateur in

    En tant que développeur, il faut souvent gérer des valeurs qui ne sont pas entièrement connues au moment de l’exécution. En fait, nous ne savons souvent pas si des propriétés existent, si nous obtenons une réponse d’un serveur ou si nous lisons un fichier de configuration. L’opérateur in de JavaScript peut vérifier si une propriété existe sur un objet.

    Auparavant, TypeScript nous permettait de restreindre tous les types qui ne répertorient pas explicitement une propriété.

    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
    interface RGB {
        red: number;
        green: number;
        blue: number;
    }
     
    interface HSV {
        hue: number;
        saturation: number;
        value: number;
    }
     
    function setColor(color: RGB | HSV) {
        if ("hue" in color) {
            // 'color' now has the type HSV
        }
        // ...
    }

    Dans l’exemple ci-dessus, le type RGB n’a pas répertorié le hue et a été réduit, nous laissant avec le type HSV. Mais qu’en est-il des exemples où aucun type ne liste une propriété donnée ? Dans ces cas, le langage n’aide pas beaucoup. Prenons l’exemple suivant en JavaScript :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function tryGetPackageName(context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    Réécrire cela en TypeScript canonique serait simplement une question de définition et d’utilisation d’un type pour context; cependant, choisir un type sûr comme unknownpour la propriété packageJSONcauserait des problèmes dans les anciennes versions de TypeScript.

    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
    19
    20
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context) {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
            //                                              ~~~~
            // error! Property 'name' does not exist on type 'object.
                return packageJSON.name;
            //                     ~~~~
            // error! Property 'name' does not exist on type 'object.
            }
        }
     
        return undefined;
    }

    En effet, alors que le type de packageJSON était réduit de unknown à object, l’opérateur in était strictement limité aux types qui définissaient réellement la propriété vérifiée. En conséquence, le type de packageJSONest resté object.

    TypeScript 4.9 rend l’opérateur in un peu plus puissant lors de la réduction des types qui ne répertorient pas du tout la propriété. Au lieu de les laisser tels quels, le langage croisera leurs types avec Record<"property-key-being-checked", unknown>. Ainsi, dans l’exemple ci-dessus, packageJSONaura son type réduit de unknown à object & Record<"name", unknown>. Cela permet d’accéder directement à packageJSON.name et de réduire cela indépendamment.

    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
    interface Context {
        packageJSON: unknown;
    }
     
    function tryGetPackageName(context: Context): string | undefined {
        const packageJSON = context.packageJSON;
        // Check to see if we have an object.
        if (packageJSON && typeof packageJSON === "object") {
            // Check to see if it has a string name property.
            if ("name" in packageJSON && typeof packageJSON.name === "string") {
                // Just works!
                return packageJSON.name;
            }
        }
     
        return undefined;
    }

    TypeScript 4.9 renforce également quelques contrôles sur la façon dont inest utilisé, garantissant que le côté gauche est attribuable au type string | number | symbol et que le côté droit est attribuable à object. Cela permet de vérifier que l’on utilise des clés de propriété valides et de ne pas vérifier accidentellement les primitives.

    Les accesseurs automatiques dans les classes

    TypeScript 4.9 prend en charge une fonctionnalité à venir dans ECMAScript appelée auto-accessors. Un auto-accessor ou accesseur automatique est une déclaration de champ qui sera transformée par le runtime en une paire d’accesseurs get et set qui accèdent à un champ de sauvegarde privé. Les autoaccesseurs sont déclarés comme les propriétés sur les classes, sauf qu’ils sont déclarés avec le mot clé accessor.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Person {
        accessor name: string;
     
        constructor(name: string) {
            this.name = name;
        }
    }

    Ci-dessous, ces accesseurs automatiques transformés en get et set avec une propriété privée inaccessible.

    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
    class Person {
        #__name: string;
     
        get name() {
            return this.#__name;
        }
        set name(value: string) {
            this.#__name = name;
        }
     
        constructor(name: string) {
            this.name = name;
        }
    }

    Vérifications d’égalité sur NaN

    Un piège majeur pour les développeurs JavaScript est de vérifier la valeur NaN à l’aide des opérateurs d’égalité intégrés. Pour certains, NaN est une valeur numérique spéciale qui signifie "Not a Number". Rien n’est jamais égal à NaN– même NaN!

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN == 0)  // false
    console.log(NaN === 0) // false
     
    console.log(NaN == NaN)  // false
    console.log(NaN === NaN) // false

    Mais au moins symétriquement tout est toujours non-égal à NaN.

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    console.log(NaN != 0)  // true
    console.log(NaN !== 0) // true
     
    console.log(NaN != NaN)  // true
    console.log(NaN !== NaN) // true

    Le problème est que le type numérique principal de JavaScript est un nombre à virgule flottante, et l’analyse des nombres en JavaScript peut souvent donner NaN. À son tour, effectuer une vérification par rapport à NaN finit par être assez courant, et la bonne façon de le faire est d’utiliser Number.isNaN; mais beaucoup de gens finissent accidentellement par vérifier plutôt avec someValue === NaN.

    TypeScript se trompe désormais sur les comparaisons directes avec NaN, et suggérera plutôt d’utiliser une variante de Number.isNaN.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function validate(someValue: number) {
        return someValue !== NaN;
        //     ~~~~~~~~~~~~~~~~~
        // error: This condition will always return 'true'.
        //        Did you mean '!Number.isNaN(someValue)'?
    }

    Ce changement devrait aider à détecter les erreurs de débutants, de la même manière que TypeScript émet actuellement des erreurs lors de comparaisons avec des littéraux d’objets et de tableaux.

    Les commandes Remove Unused Imports et Sort Imports pour les éditeurs

    Auparavant, TypeScript ne prenait en charge que deux commandes d’éditeur pour gérer les importations. Le premier s’appelait Organize Imports (ou Organiser les importations) qui supprimait les importations inutilisées, puis triait celles qui restaient. Dans TypeScript 4.3, une nouvelle commande appelée Sort Imports (ou Trier les importations) qui trie uniquement les importations dans le fichier, mais ne les supprime pas a été ajoutée. La mise en garde avec la commande Sort Imports était que dans Visual Studio Code, cette fonctionnalité n’était disponible qu’en tant que commande à l’enregistrement, et non en tant que commande déclenchable manuellement.

    TypeScript 4.9 ajoute l’autre moitié et fournit désormais Remove Unsed Imports (pour Supprimer les importations inutilisées). TypeScript supprimera désormais les noms et instructions d’importation inutilisés, mais laissera par ailleurs l’ordre relatif.

    Substitute remplacé par constraint  sur les objets SubstitutionTypes 

    Dans le cadre d’une optimisation sur les types de substitution, les objets SubstitutionType  ne contiennent plus la propriété substitute représentant la substitution effective (généralement une intersection du type de base et de la contrainte implicite) – au lieu de cela, ils contiennent simplement la propriété constraint .

    Au-delà ce des nouveautés introduites dans cette dernière version de TypeScript, plusieurs autres améliorations sont également disponibles comme des améliorations de performances, des corrections de bogues et bien plus encore.

    Source : Microsoft

    Et vous ?

    Avez-vous testé la nouvelle version de TypeScript ? répond-elle à vos attentes ?

    Quelles sont les fonctionnalités que vous avez aimées le plus ou le moins dans cette dernière version de TypeScript ?

    Voir aussi

    TypeScript 4.9 Beta est disponible et apporte la restriction des propriétés non listées avec l’opérateur in, ainsi que la vérification de l’égalité sur NaN
    TypeScript 4.7 Beta s’accompagne de la prise en charge du module ECMAScript dans Node.js et propose un contrôle de la détection de module
    TypeScript 4.3 est disponible et apporte le mot-clé override pour qu’un dev puisse indiquer clairement s’il avait l’intention d’ajouter une nouvelle méthode ou de remplacer une méthode existante
    Microsoft publie TypeScript 4.2 avec la prise en charge de Abstract Constructor Types et des contrôles plus stricts pour l’opérateur in

Discussions similaires

  1. TypeScript 4.5 est disponible et apporte des améliorations au type Awaited
    Par Stéphane le calme dans le forum TypeScript
    Réponses: 0
    Dernier message: 18/11/2021, 10h37
  2. Réponses: 1
    Dernier message: 28/05/2021, 00h15
  3. Réponses: 1
    Dernier message: 29/08/2019, 14h56
  4. Réponses: 5
    Dernier message: 18/03/2019, 07h25
  5. Réponses: 3
    Dernier message: 03/12/2015, 12h26

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