AccueilActualités informatiqueLangage de programmation : TypeScript 4.5 jongle avec les modules Node.js

Langage de programmation : TypeScript 4.5 jongle avec les modules Node.js

Microsoft a publié la première version bêta de TypeScript 4.5. Cette version apporte des ajustements pour l’interaction avec les modules ECMAScript dans Node.js. Il supprime également les appels de fonction récursifs dans certains cas et reprend deux innovations prévues dans la norme ECMAScript.

Sommaire

Node.js peut désormais gérer les modules ECMAScript (ESM) en plus du système de modules traditionnellement utilisé, CommonJS (CJS). Pour l’interaction, TypeScript 4.5 introduit un nouveau système de modules sous l’appellation compilerOptions le site module-réglages node12 et nodenext sur.

Les nouveaux modes de module vérifient si un fichier .ts-., .tsx-., .js-. ou .jsx est un module ES. Dans ce cas, le système traite les importations d’autres modules conformément aux directives de l’ESM. Entre autres choses, les chemins d’importation relatifs doivent contenir l’extension du nom du fichier. Par exemple, la spécification import "./foo.js" tandis que pour CJS import "./foo") est autorisé sans fin.

Le type de module peut fondamentalement être défini dans Node.js d’une part dans package.json via l’entrée "type": "module" ou "type": "commonjs" comme module ESM ou CJS respectivement. En outre, Node.js permet une spécification explicite via l’extension de fichier : .mjs pour EMS et .cjs pour CJS. De même, TypeScript 4.5 introduit les extensions .mts et .cts.

Deux changements concernent les optimisations de TypeScript sous le capot. Par exemple, le système tente de détecter si une récursion s’exécute potentiellement à l’infini ou si une expansion de type prend un temps très long. Certains types peuvent déclencher de manière incorrecte l’heuristique que TypeScript utilise pour les détecter. À titre d’exemple, l’article de blog présente un extrait de code qui supprime les espaces en tête des types de chaînes de caractères :

type TrimLeft<T extends string> =
    T extends ` ${infer Rest}` ? TrimLeft<Rest> : T;

// Test = "hello" | "world"
type Test = TrimLeft<"   hello" | " world">;

Pour le code d’exemple, l’implémentation fonctionne. Cependant, si une chaîne de caractères comporte beaucoup d’espaces au début, la détection heuristique conduit au message d’erreur suivant

error: Type instantiation is excessively deep
and possibly infinite.

Dans le cas d’utilisation concret, cependant, l’overhead est moins critique car la fonction est end-récursive dans une branche et renvoie directement le résultat sans le traiter davantage. TypeScript 4.5 a récemment supprimé les appels de fonction terminaux si une branche du type conditionnel est elle-même un type conditionnel. De cette façon, aucune instanciation supplémentaire n’est nécessaire, ce qui pourrait conduire les besoins en mémoire de la fonction récursive à l’infini.

TypeScript 4.5 introduit également le nouveau paramètre --preserveValueImports ce qui empêche la suppression automatique des importations apparemment inutilisées. À titre d’exemple, l’article de blog accède à un extrait de code avec eval :

import { Animal } from "./animal.js";

eval("console.log(new Animal().isDangerous())");

Même si, en principe, l’utilisation de eval dans TypeScript et JavaScript est discutable pour des raisons de sécurité uniquement, l’exemple démontre un cas dans lequel TypeScript peut considérer à tort une importation comme superflue et la supprimer parce que le module JavaScript est utilisé dans la chaîne. Il en va de même pour l’interaction avec des frameworks tels que Vue.js ou Svelte. Dans ce cas, certaines importations ne sont pas immédiatement reconnaissables par le système de construction car elles sont en script-passages.

Avec deux nouvelles fonctionnalités, TypeScript reprend des suggestions ECMAScript qui n’existent pas encore dans la norme mais qui sont prévues. Tout d’abord, TypeScript peut vérifier si un objet contient un champ privé qui est défini dans la classe actuelle :

class Person {
    #name: string;
    constructor(name: string) {
        this.#name = name;
    }

    equals(other: unknown) {
        return other &&
            typeof other === "object" &&
            #name in other && // <- this is new!
            this.#name === other.#name;
    }
}

La proposition correspondante de l’ECMA est intitulée « Ergonomic brand checks for private fields ». Les champs privés peuvent être utilisés pour vérifier s’il s’agit effectivement d’une instance de la classe, car ils n’existent que dans ce cas.

En outre, les assertions d’importation également prévues pour ECMAScript peuvent être utilisées dans TypeScript 4.5. Ils garantissent qu’un fichier importé a un certain format.

import obj from "./something.json" assert { type: "json" };

Toutefois, le système de compilation ne se charge pas de la vérification du format du contenu, car cette responsabilité incombe au navigateur ou au moteur d’exécution.

Vous trouverez d’autres innovations dans TypeScript 4.5 sur le blog de développement de Microsoft. La phase bêta de TypeScript 4.5 est prévue pour six bonnes semaines, et la version finale devrait apparaître le 16 novembre 2021 selon la feuille de route.

Plus d'articles