AccueilActualités informatiqueLangage de programmation : TypeScript 4.5 renonce finalement aux modules ECMAScript

Langage de programmation : TypeScript 4.5 renonce finalement aux modules ECMAScript

Microsoft a publié TypeScript 4.5 comme prévu. Cette version apporte surtout des optimisations sous le capot et anticipe deux nouveautés prévues dans la norme ECMAScript, qui concernent les champs privés et les fichiers importés.

Lors du lancement de la phase bêta début octobre, il était prévu d’étendre le système de modules afin de pouvoir traiter non seulement CommonJS (CJS) mais aussi ECMAScript Modules (ESM) en interaction avec Node.js. Toutefois, l’équipe a fait marche arrière dès la publication de la Release Candidate. L’une des raisons en est, selon l’issue correspondante sur GitHub, des bugs qui doivent encore être corrigés.

Les doutes concernant l’utilisabilité sont plus importants. La rédaction correcte de paquets est déjà suffisamment difficile, et le projet d’une nouvelle version de l’interface utilisateur ne fait pas exception à la règle. node12-créerait une confusion supplémentaire. C’est pourquoi l’équipe veut continuer à travailler sur la mise en œuvre afin d’éviter que les auteurs de paquets n’utilisent mal les modules et ne se mettent ainsi le doigt dans l’œil.

Sommaire

Les autres fonctionnalités de la version bêta sont incluses dans la version GA. Cela concerne entre autres l’heuristique pour détecter les récursions qui s’exécutent potentiellement à l’infini et les extensions de type qui prennent beaucoup de temps à s’exécuter. L’extrait de code suivant, tiré du blog TypeScript, sert d’exemple TrimLeft-supprime les espaces de début d’un type de type chaîne de caractères :

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

// error: Type instantiation is excessively deep 
// and possibly infinite.
type Test = 
 TrimLeft<"                                                oops">;

Jusqu’à présent, le code déclenchait un message d’erreur en raison de la récursivité profonde avec les nombreux espaces à supprimer. Cependant, la fonction d’exemple est récursive en fin de branche. Depuis peu, TypeScript 4.5 supprime les appels de fonction terminaux lorsqu’une branche du type conditionnel est elle-même un type conditionnel. De cette manière, il n’est pas nécessaire de procéder à des instanciations supplémentaires, ce qui augmente potentiellement à l’infini les besoins en mémoire de la fonction récursive.

Également nouveau, le Awaited-qui peut être utilisé entre autres pour l’interaction avec des await dans async-ou les fonctions .then()-dans Promise a été conçue. La motivation était probablement la mise en œuvre de Promise.all()comme le montre l’exemple de code suivant, qui a été réalisé jusqu’à présent sans le Awaited-a donné lieu à un message d’erreur :

declare function 
  MaybePromise<T>(value: T): T | Promise<T> | PromiseLike<T>;

async function doSomething(): Promise<[number, number]> {
    const result = await Promise.all([
        MaybePromise(100),
        MaybePromise(200)
    ]);

    // Error!
    //
    //    [number | Promise<100>, number | Promise<200>]
    //
    // is not assignable to type
    //
    //    [number, number]
    return result;
}

D’autres exemples et une explication plus détaillée se trouvent dans la Pull Request correspondante sur GitHub.

Le nouveau paramètre --preserveValueImports empêche la suppression automatique des importations qui semblent ne pas être utilisées. L’article de blog cite en exemple un extrait de code contenant eval est cité :

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

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

En principe, l’utilisation de eval dans TypeScript et JavaScript est déjà discutable pour des raisons de sécurité, mais l’exemple démontre un cas où TypeScript peut considérer à tort une importation comme superflue et la supprimer, car il ne reconnaît pas le module JavaScript utilisé dans la chaîne de caractères. Il en va de même pour l’interaction avec des frameworks comme Vue.js ou Svelte. Dans ce cas, le système de construction ne reconnaît pas d’emblée certaines importations comme étant utilisées, car elles sont contenues dans le fichier script-sont intégrés dans des passages.

Deux nouveautés reprennent des propositions d’ECMAScript qui n’existent pas encore dans le standard, mais qui sont prévues. D’une part, TypeScript peut vérifier si un objet contient un champ privé défini dans la classe actuelle. La proposition correspondante de l’ECMA s’intitule « Ergonomic brand checks for Private Fields » (traduisible par « vérification ergonomique des variétés pour les champs privés »). Les champs privés permettent de vérifier s’il s’agit effectivement d’une instance de la classe, car ils n’existent que dans ce cas.

Par ailleurs, les développeurs peuvent utiliser les Import Assertions également prévues pour ECMAScript dans TypeScript 4.5. Elles permettent de s’assurer qu’un fichier importé a un format spécifique :

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

Le système de construction ne vérifie que le format indiqué et non le contenu réel. Pour ce dernier, la responsabilité incombe au navigateur ou au runtime.

D’autres nouveautés de TypeScript 4.5, comme la connexion étendue à JSDoc et l’autocomplétion des snippets pour les méthodes de classe, sont disponibles sur le blog de développement de Microsoft. La version est disponible via NuGet ou peut être téléchargée en cliquant sur le lien suivant npm install typescript à installer.

Plus d'articles