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 :

TypeScript 3.8 est disponible avec l'implémentation de la syntaxe « export * as ns »


Sujet :

TypeScript

  1. #1
    Chroniqueur Actualités

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Mars 2013
    Messages
    8 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Mars 2013
    Messages : 8 456
    Points : 197 841
    Points
    197 841
    Par défaut TypeScript 3.8 est disponible avec l'implémentation de la syntaxe « export * as ns »
    TypeScript 3.8 RC apporte une nouvelle syntaxe pour l'importation/exportation de types uniquement,
    ainsi que les champs privés ECMAScript

    Imports et exports d'un type en particulier

    TypeScript réutilise la syntaxe d'importation de JavaScript afin de nous permettre de référencer les types. Par exemple, dans l'exemple suivant, nous pouvons importer doThing qui est une valeur JavaScript avec Options qui est purement un type 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
    // ./foo.ts
    interface Options {
        // ...
    }
     
    export function doThing(options: Options) {
        // ...
    }
     
    // ./bar.ts
    import { doThing, Options } from "./foo.js";
     
    function doThingBetter(options: Options) {
        // do something twice as good
        doThing(options);
        doThing(options);
    }

    C'est pratique parce que la plupart du temps, nous n'avons pas à nous soucier de ce qui est importé, mais uniquement de nous assurer que nous importons bien quelque chose. Malheureusement, cela n'a fonctionné qu'en raison d'une fonctionnalité appelée élision d'importation. Lorsque TypeScript génère des fichiers JavaScript, il voit que Options n'est utilisé que comme type et supprime automatiquement son importation. La sortie résultante ressemble un peu à ceci:

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // ./foo.js
    export function doThing(options: Options) {
        // ...
    }
     
    // ./bar.js
    import { doThing } from "./foo.js";
     
    function doThingBetter(options: Options) {
        // do something twice as good
        doThing(options);
        doThing(options);
    }

    Encore une fois, ce comportement est généralement bien, mais il provoque d'autres problèmes. Tout d’abord, il existe des endroits où il est ambigu d’exporter une valeur ou un type. Par exemple, dans l'exemple suivant, MyThing est-il une valeur ou un type ?

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import { MyThing } from "./some-module.js";
     
    export { MyThing };

    En nous limitant à ce fichier, il n'y a aucun moyen de le savoir. L'API transpileModule de Babel et de TypeScript émettra du code qui ne fonctionnera pas correctement si MyThing n'est qu'un type, et l'indicateur isolatedModules de TypeScript nous avertira que ce sera un problème. Le vrai problème ici est qu'il n'y a aucun moyen de dire « non non, en fait je voulais faire appel au type, ceci devrait être effacé », donc l'importation d'élision n'est pas suffisante.

    L’autre problème était que l’élision d’importation de TypeScript supprimait les instructions d’importation qui ne contenaient que les importations utilisées comme types. Cela a provoqué un comportement sensiblement différent pour les modules qui ont des effets secondaires, et les utilisateurs devraient donc insérer une deuxième instruction d'importation uniquement pour contrer les effets secondaires.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // This statement will get erased because of import elision.
    import { SomeTypeFoo, SomeOtherTypeBar } from "./module-with-side-effects";
     
    // This statement always sticks around.
    import "./module-with-side-effects";

    Un cas concret où l'équipe TypeScript a vu cela arriver était dans des frameworks comme Angular.js (1.x) où les services devaient être enregistrés globalement (ce qui est un effet secondaire), mais où ces services n'étaient importés que pour les types.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // ./service.ts
    export class Service {
        // ...
    }
    register("globalServiceId", Service);
     
    // ./consumer.ts
    import { Service } from "./service.js";
     
    inject("globalServiceId", function (service: Service) {
        // do stuff with Service
    });

    Par conséquent, ./service.js ne sera jamais exécuté et les choses vont planter lors de l'exécution.

    Pour éviter ce type de problèmes, l'équipe a réalisé qu'elle devait donner aux utilisateurs un contrôle plus fin sur la façon dont les choses étaient importées/élidées.

    En tant que solution dans TypeScript 3.8, l'équipe a ajouté une nouvelle syntaxe pour les importations et exportations de type uniquement.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import type { SomeThing } from "./some-module.js";
     
    export type { SomeThing };

    import type importe uniquement les déclarations à utiliser pour les annotations et les déclarations de type. Il est toujours entièrement effacé, il n'y a donc pas de reste à l'exécution. De même, export type fournit uniquement une exportation qui peut être utilisée pour les contextes de type et est également effacé de la sortie de TypeScript.

    Il est important de noter que les classes ont une valeur au moment de l'exécution et un type au moment du design, et l'utilisation est très sensible au contexte. Lorsque vous utilisez import type pour importer une classe, vous ne pouvez pas faire des choses comme faire une extension à partir de celle-ci.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import type { Component } from "react";
     
    interface ButtonProps {
        // ...
    }
     
    class Button extends Component<ButtonProps> {
        //               ~~~~~~~~~
        // error! 'Component' only refers to a type, but is being used as a value here.
     
        // ...
    }

    Si vous avez déjà utilisé Flow, la syntaxe est assez similaire. Une différence est que l'équipe TypeScript a ajouté quelques restrictions pour éviter le code qui pourrait apparaître ambigu.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Is only 'Foo' a type? Or every declaration in the import?
    // We just give an error because it's not clear.
     
    import type Foo, { Bar, Baz } from "some-module";
    //     ~~~~~~~~~~~~~~~~~~~~~~
    // error! A type-only import can specify a default import or named bindings, but not both.

    En conjonction avec import type, l'équipe TypeScript a également ajouté un nouvel indicateur de compilateur pour contrôler ce qui se passe avec les importations qui ne seront pas utilisées au moment de l'exécution: importsNotUsedAsValues. Ce drapeau prend 3 valeurs différentes:

    remove: c'est le comportement actuel de l'abandon de ces importations. Ce sera toujours la valeur par défaut.
    preserve : cette valeur préserve toutes les importations dont les valeurs ne sont jamais utilisées. Cela peut entraîner la préservation des importations/effets secondaires.
    error : cette valeur préserve toutes les importations (la même que l'option preserve), mais va provoquer une erreur lorsqu'une importation de valeur n'est utilisée que comme type. Cela peut être utile si vous voulez vous assurer qu'aucune valeur n'est importée accidentellement, tout en rendant les importations d'effets secondaires explicites.

    Nom : typescript.png
Affichages : 11263
Taille : 20,2 Ko

    Champs privés ECMAScript

    TypeScript 3.8 prend en charge les champs privés d'ECMAScript, qui font partie de la proposition de champs de classe de stade 3.

    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
    class Person {
        #name: string
     
        constructor(name: string) {
            this.#name = name;
        }
     
        greet() {
            console.log(`Hello, my name is ${this.#name}!`);
        }
    }
     
    let jeremy = new Person("Jeremy Bearimy");
     
    jeremy.#name
    //     ~~~~~
    // Property '#name' is not accessible outside class 'Person'
    // because it has a private identifier.

    Contrairement aux propriétés régulières (même celles déclarées avec le modificateur private), les champs privés ont quelques règles à garder à l'esprit. Certaines d'entre elles sont:
    • Les champs privés commencent par un caractère #. Parfois, nous les appelons noms privés.
    • Chaque nom de champ privé a une portée unique dans sa classe conteneur.
    • Les modificateurs d'accessibilité TypeScript comme public ou private ne peuvent pas être utilisés sur des champs privés.
    • Les champs privés ne peuvent pas être accédés ou même détectés en dehors de la classe contenant.

    Les déclarations de propriétés régulières sont sujettes à être écrasées dans les sous-classes :

    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
    class C {
        foo = 10;
     
        cHelper() {
            return this.foo;
        }
    }
     
    class D extends C {
        foo = 20;
     
        dHelper() {
            return this.foo;
        }
    }
     
    let instance = new D();
    // 'this.foo' refers to the same property on each instance.
    console.log(instance.cHelper()); // prints '20'
    console.log(instance.dHelper()); // prints '20'

    Avec les champs privés, vous n'aurez jamais à vous en préoccuper, car chaque nom de champ est unique à la classe contenante.

    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
    class C {
        #foo = 10;
     
        cHelper() {
            return this.#foo;
        }
    }
     
    class D extends C {
        #foo = 20;
     
        dHelper() {
            return this.#foo;
        }
    }
     
    let instance = new D();
    // 'this.#foo' refers to a different field within each class.
    console.log(instance.cHelper()); // prints '10'
    console.log(instance.dHelper()); // prints '20'

    Une autre chose à noter est que l'accès à un champ privé sur n'importe quel autre type entraînera une TypeError!

    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
    class Square {
        #sideLength: number;
     
        constructor(sideLength: number) {
            this.#sideLength = sideLength;
        }
     
        equals(other: any) {
            return this.#sideLength === other.#sideLength;
        }
    }
     
    const a = new Square(100);
    const b = { sideLength: 100 };
     
    // Boom!
    // TypeError: attempted to get private field on non-instance
    // This fails because 'b' is not an instance of 'Square'.
    console.log(a.equals(b));

    Enfin, pour tout utilisateur de fichier .js ordinaire, les champs privés doivent toujours être déclarés avant d'être attribués.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class C {
        // No declaration for '#foo'
        // :(
     
        constructor(foo: number) {
            // SyntaxError!
            // '#foo' needs to be declared before writing to it.
            this.#foo = foo;
        }
    }

    JavaScript a toujours permis aux utilisateurs d'accéder aux propriétés non déclarées, tandis que TypeScript a toujours exigé des déclarations pour les propriétés de classe. Avec les champs privés, les déclarations sont toujours nécessaires, que nous travaillions dans des fichiers .js ou .ts.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class C {
        /** @type {number} */
        #foo;
     
        constructor(foo: number) {
            // This works.
            this.#foo = foo;
        }
    }

    Syntaxe export * as ns

    Il est souvent courant d'avoir un point d'entrée unique qui expose tous les membres d'un autre module comme un seul membre.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import * as utilities from "./utilities.js";
    export { utilities };

    C'est tellement courant qu'ECMAScript 2020 a récemment ajouté une nouvelle syntaxe pour prendre en charge ce modèle!

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

    Il s'agit d'une belle amélioration apportée à la qualité de JavaScript, et TypeScript 3.8 implémente cette syntaxe. Lorsque la cible de votre module est antérieure à es2020, TypeScript affichera quelque chose dans le sens du premier extrait de code.

    Changements

    TypeScript 3.8 contient quelques changements mineurs qui doivent être notés.

    Contrôles d'assignation plus stricts aux unions avec des signatures d'index

    Auparavant, les propriétés excédentaires n'étaient pas cochées lors de l'affectation à des unions où tout type avait une signature d'index - même si cette propriété excédentaire ne pouvait jamais satisfaire cette signature d'index. Dans TypeScript 3.8, le vérificateur de type est plus strict et « exempte » uniquement les propriétés des vérifications de propriétés excédentaires si cette propriété peut vraisemblablement satisfaire une signature d'index.

    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
    const obj1: { [x: string]: number } | { a: number };
     
    obj1 = { a: 5, c: 'abc' }
    //             ~
    // Error!
    // The type '{ [x: string]: number }' no longer exempts 'c'
    // from excess property checks on '{ a: number }'.
     
    let obj2: { [x: string]: number } | { [x: number]: number };
     
    obj2 = { a: 'abc' };
    //       ~
    // Error!
    // The types '{ [x: string]: number }' and '{ [x: number]: number }' no longer exempts 'a'
    // from excess property checks against '{ [x: number]: number }',
    // and it *is* sort of an excess property because 'a' isn't a numeric property name.
    // This one is more subtle.

    object dans JSDoc n'est plus any sous noImplicitAny

    Historiquement, la prise en charge de TypeScript pour la vérification de JavaScript a été laxiste à certains égards afin de fournir une expérience accessible.

    Par exemple, les utilisateurs ont souvent utilisé Object dans JSDoc pour signifier « un objet, je ne sais pas quoi », il était alors traité comme any.

    Code TypeScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // @ts-check
     
    /**
     * @param thing {Object} some object, i dunno what
     */
    function doSomething(thing) {
        let x = thing.x;
        let y = thing.y;
        thing();
    }

    En fait, le traiter comme le type Object de TypeScript aboutirait à du code signalant des erreurs inintéressantes, car le type Object est un type extrêmement vague avec peu de capacités autres que des méthodes telles que toString et valueOf.

    Cependant, TypeScript a un object nommé de type plus utile (notez que "o" est minuscule). Le type object est plus restrictif que Object, en ce sens qu'il rejette tous les types primitifs tels que string, boolean et number. Malheureusement, Object et object ont été traités comme any dans JSDoc.

    Parce que object peut être utile et est utilisé beaucoup moins que Object dans JSDoc, l'équipe TypeScript a supprimé le comportement de cas spécial dans les fichiers JavaScript lors de l'utilisation de noImplicitAny afin que dans JSDoc, le type object se réfère vraiment au type d'objet non primitif.

    Source : TypeScript
    Contribuez au club : Corrections, suggestions, critiques, ... : Contactez le service news et Rédigez des actualités

  2. #2
    Chroniqueur Actualités

    Homme Profil pro
    Dirigeant
    Inscrit en
    Juin 2016
    Messages
    3 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : Dirigeant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2016
    Messages : 3 160
    Points : 66 259
    Points
    66 259
    Par défaut TypeScript 3.8 est disponible avec l'implémentation de la syntaxe « export * as ns »
    TypeScript 3.8 est disponible avec l'implémentation de la syntaxe « export * as ns »
    et prend en charge les champs privés d'ECMAScript

    Microsoft a annoncé hier la sortie de la version stable de TypeScript 3.8. Elle apporte de nouvelles fonctionnalités comme l'a montré la RC publiée par Microsoft il y a deux semaines. Ces fonctionnalités comprennent l’importation et l’exportation de types uniquement, les champs privés de ECMAScript, etc. Voici de quoi il s’agit dans cette version :

    L’importation et l’exportation de types uniquement

    Avec les versions antérieures de TypeScript, l’importation et l’exportation de types fonctionnent avec l’élision des importations. Mais, il y a une ambiguïté qui survient lorsqu'il n'est pas clair s'il s'agit d'un type ou d'une valeur qui est importée. De plus, les déclarations d'importation qui ne contiennent que des importations utilisées comme types sont éliminées par l'élision d'importation de TypeScript. Pour contourner ces problèmes, TypeScript 3.8 ajoute désormais une nouvelle syntaxe pour l'importation et l'exportation des types uniquement. TypeScript 3.8 réutilise la syntaxe d'importation de JavaScript afin de vous permettre de référencer les types. Voici à quoi cela ressemble :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import type { SomeThing } from "./some-module.js";
    export type { SomeThing };
    L'instruction “import type” n'importe que les déclarations à utiliser pour les annotations et les déclarations de type. En plus, elle est toujours entièrement effacée lors de la transposition. Ensuite, l’instruction “export type” fournit uniquement une exportation pour les contextes de type, et est également effacée de la sortie de TypeScript. Lorsque vous utilisez la commande “import type” pour importer une classe, elle ne pourra pas être étendue par la suite. Par ailleurs, le compilateur TypeScript introduit un nouveau drapeau, importsNotUsedAsValues.

    Cela sert à déterminer ce qu'il advient des importations non utilisées au moment de l'exécution. Les valeurs de ce drapeau, “remove”, “preserve” ou “error”, permettent aux développeurs de mieux contrôler l'importation et l'exportation des types.

    Les champs privés ECMAScript

    TypeScript 3.8 prend en charge les champs privés d'ECMAScript, qui font partie de la proposition de champs de classe de stade 3. Les champs privés commencent par un caractère # et sont uniquement limités à leur classe de contenu. Les modificateurs TypeScript comme public ou private ne peuvent pas être utilisés sur les champs privés. De même, les champs privés ne peuvent pas être accédés ou détectés en dehors de la classe qui les contient.

    Nom : z1.png
Affichages : 3724
Taille : 35,2 Ko

    Ils sont différents du mot clé “privé” de TypeScript. La prise en charge de ces champs n’est pas encore totale. Selon Microsoft, TypeScript ne prend actuellement en charge que la transposition des champs privés vers ES6 et plus. L'implémentation rétrocompatible exploite les WeakMaps, alors que le mot clé “privé” fonctionne de nouveau vers ES3.

    La syntaxe export * as ns

    TypeScript 3.8 introduit la syntaxe export * de la norme ECMAScript 2020 permettant d’exposer tous les membres d'un module comme un seul membre.
    En outre, TypeScript 3.8 prend désormais en charge ES2020 comme cible de transpilation et option de module. Il préserve les fonctionnalités ES2020 ajoutées dans TypeScript 3.7 et 3.8. La version 3.8 de TypeScript améliore son support de surveillance des répertoires et ajoute un nouveau champ de configuration du compilateur watchOptions. Cela donne aux développeurs un plus grand contrôle sur la façon dont les répertoires et les fichiers sont surveillés, améliorant les performances et la fiabilité du travail avec les modifications apportées aux node_modules.

    Le champ watchOptions offre quatre nouvelles options : watchFile, watchDirectory, fallbackPolling et synchronousWatchDirectory, chacune d'entre elles ayant plusieurs options de configuration pour la fréquence de vérification des fichiers et des répertoires. Pour finir, le compilateur de TypeScript 3.8 ajoute une autre option d'optimisation des performances, assumeChangesOnlyAffectDirectDependencies, qui indique à TypeScript de ne vérifier et reconstruire que les fichiers qui ont été modifiés ainsi que les fichiers qui les importent directement.

    Pour chaque version de TypeScript, le compilateur introduit des modifications de rupture à mesure que ses capacités de vérification de type s'améliorent. Dans TypeScript 3.8, le compilateur ajoute des contrôles d'assignabilité plus stricts aux unions avec des signatures d'index.

    Source : Microsoft

    Et vous ?

    Que pensez-vous des nouveautés dans TypeScript 3.8 ?

    Voir aussi

    TypeScript 3.8 RC apporte une nouvelle syntaxe pour l'importation/exportation de types uniquement, ainsi que les champs privés ECMAScript

    La version stable de TypeScript 3.7.0 est disponible et apporte diverses fonctionnalités et quelques améliorations au langage

    La version bêta de TypeScript 3.7.0 est disponible avec la prise en charge de l'opérateur de chaînage d'optionnels (?.) et l'opérateur (??)

    TypeScript 3.6 est disponible et apporte le support de import.meta dans SystemJS et des API qui prennent en charge --build et --incremental
    Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/09/2018, 15h33
  2. Réponses: 0
    Dernier message: 04/11/2017, 22h12
  3. Réponses: 52
    Dernier message: 28/06/2012, 16h36
  4. [Joomla!] Joomla 1.6 est disponible avec l'arrivée du code sémantique
    Par Idelways dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 18
    Dernier message: 18/03/2011, 10h04
  5. Joomla 1.6 est disponible avec l'arrivée du code sémantique
    Par Idelways dans le forum Actualités
    Réponses: 17
    Dernier message: 18/01/2011, 19h33

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