IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

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

Le , par Jade Emy

28PARTAGES

13  0 
Microsoft annonce la disponibilité de TypeScript 5.6. Parmi les mises à jour : améliorations des vérifications vraies et nulles non autorisées, de nouvelles méthodes d'aide à l'itérateur, prise en charge d'identifiants de modules arbitraires, améliorations des vérifications strictes des itérateurs intégrés, l'introduction des options --noUncheckedSideEffectImports et --noCheck, et d'autres changements de comportements notables.

TypeScript est un langage qui s'appuie sur JavaScript en ajoutant une syntaxe pour les types. Les types décrivent les formes attendues des variables, paramètres et fonctions, et le vérificateur de type TypeScript peut aider à détecter des problèmes tels que les fautes de frappe, les propriétés manquantes et les mauvais appels de fonction avant l'exécution du code. Les types alimentent également les outils d'édition de TypeScript, comme l'auto-complétion, la navigation dans le code et les refactorisations dans des éditeurs tels que Visual Studio et VS Code. En fait, si vous écrivez du JavaScript dans l'un ou l'autre de ces éditeurs, cette expérience est alimentée par TypeScript !

Microsoft vient d'annoncer la sortie de TypeScript 5.6. Depuis la version bêta de TypeScript 5.6, l'équipe de TypeScript est revenu sur un changement concernant la façon dont le service de langage TypeScript recherche les fichiers tsconfig.json. Auparavant, le service de langage n'arrêtait pas de chercher tous les fichiers de projet nommés tsconfig.json susceptibles de contenir un fichier. Comme cela pouvait conduire à l'ouverture de nombreux projets référencés, ce comportement a été annulée pour TypeScript 5.6. Elle pourrait revenir dans TypeScript 5.7.

En outre, plusieurs nouveaux types ont été renommés depuis la version bêta. Auparavant, TypeScript fournissait un seul type appelé BuiltinIterator pour décrire chaque valeur soutenue par Iterator.prototype. Il a été renommé IteratorObject, a un ensemble différent de paramètres de type, et a maintenant plusieurs sous-types comme ArrayIterator, MapIterator, et plus encore.

Un nouveau drapeau appelé --stopOnBuildErrors a été ajouté pour le mode --build. Lorsqu'un projet se construit avec des erreurs, aucun autre projet ne sera construit. Cela permet de se rapprocher du comportement des versions précédentes de TypeScript puisque TypeScript 5.6 construit toujours en cas d'erreur.

De nouvelles fonctionnalités de l'éditeur ont été ajoutées, telles que le support direct des caractères de validation et des motifs d'exclusion pour les auto-importations.


Voici quelques mises à jours de cette version :

Vérifications vraies et nulles non autorisées

Voici quelques exemples d'erreurs qui ne correspondent pas à l'intention de l'auteur, mais ils constituent tous du code JavaScript valide.

  • Ecrire une regex et oublié d'appeler .test(...) dessus
  • Ecrire => (qui crée une fonction flèche) au lieu de >= (l'opérateur plus grand que ou égal à)
  • Utiliser une valeur par défaut avec ? ?, mais confondre la priorité de ? ? et d'un opérateur de comparaison comme <
  • Mal placer une parenthèse dans une expression complexe


Auparavant, TypeScript acceptait aussi ces exemples. Mais de nombreux bogues pouvaient être détectés en signalant ces exemples suspects.

Dans TypeScript 5.6, le compilateur fait désormais des erreurs lorsqu'il peut déterminer syntaxiquement qu'une vérification vraie ou nulle sera toujours évaluée d'une manière spécifique. Ainsi, dans les exemples ci-dessus, vous commencerez à voir des erreurs :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
if (/0x[0-9a-f]/) {
//  ~~~~~~~~~~~~
// error: This kind of expression is always truthy.
}
 
if (x => 0) {
//  ~~~~~~
// error: This kind of expression is always truthy.
}
 
function isValid(value: string | number, options: any, strictness: "strict" | "loose") {
    if (strictness === "loose") {
        value = +value
    }
    return value < options.max ?? 100;
    //     ~~~~~~~~~~~~~~~~~~~
    // error: Right operand of ?? is unreachable because the left operand is never nullish.
}
 
if (
    isValid(primaryValue, "strict") || isValid(secondaryValue, "strict") ||
    isValid(primaryValue, "loose" || isValid(secondaryValue, "loose"))
) {
    //                    ~~~~~~~
    // error: This kind of expression is always truthy.
}
Des résultats similaires peuvent être obtenus en activant la règle ESLint no-constant-binary-expression ; mais les nouvelles vérifications effectuées par TypeScript ne se chevauchent pas parfaitement avec la règle ESLint.

Notez que certaines expressions sont toujours autorisées, même si elles sont toujours vraies ou nulles. Plus précisément, true, false, 0 et 1 sont toujours autorisés même si elles sont toujours vraies ou fausses.

Méthodes d'aide pour les itérateurs

JavaScript a une notion d'itérables (choses sur lesquelles on peut itérer en appelant un [Symbol.iterator]() et en obtenant un itérateur) et d'itérateurs (choses qui ont une méthode next() que l'on peut appeler pour essayer d'obtenir la valeur suivante au fur et à mesure de l'itération). En général, il n'est pas nécessaire de penser à ces choses lorsque vous les placez dans une boucle for/of, ou [...spread] dans un nouveau tableau. Mais TypeScript les modélise avec les types Iterable et Iterator (et même IterableIterator qui agit comme les deux !), et ces types décrivent l'ensemble minimal de membres dont vous avez besoin pour que des constructions comme for/of fonctionnent sur eux.

Les Iterables (et les IterableIterators) sont intéressants car ils peuvent être utilisés dans toutes sortes d'endroits en JavaScript - mais beaucoup de gens se sont aperçus qu'il manquait des méthodes sur les Arrays comme map, filter, et pour une raison ou une autre reduce. C'est pourquoi une proposition récente a été présentée dans ECMAScript pour ajouter de nombreuses méthodes (et plus) de Array à la plupart des IterableIterators qui sont produits en JavaScript.

Par exemple, chaque générateur produit désormais un objet qui possède également une méthode map et une méthode take.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function* positiveIntegers() {
    let i = 1;
    while (true) {
        yield i;
        i++;
    }
}
 
const evenNumbers = positiveIntegers().map(x => x * 2);
 
// Output:
//    2
//    4
//    6
//    8
//   10
for (const value of evenNumbers.take(5)) {
    console.log(value);
}
Il en va de même pour les méthodes telles que keys(), values() et entries() sur les Maps et les Sets.

Code : Sélectionner tout
1
2
3
4
5
function invertKeysAndValues<K, V>(map: Map<K, V>): Map<V, K> {
    return new Map(
        map.entries().map(([k, v]) => [v, k])
    );
}
Vous pouvez également étendre le nouvel objet Iterator:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * Provides an endless stream of `0`s.
 */
class Zeroes extends Iterator<number> {
    next() {
        return { value: 0, done: false } as const;
    }
}
 
const zeroes = new Zeroes();
 
// Transform into an endless stream of `1`s.
const ones = zeroes.map(x => x + 1);
et vous pouvez adapter n'importe quel Iterable ou Iterator existant à ce nouveau type avec Iterator.from :

Code : Sélectionner tout
Iterator.from(...).filter(someFunction);
Toutes ces nouvelles méthodes fonctionnent tant que vous utilisez un runtime JavaScript plus récent, ou que vous utilisez un polyfill pour le nouvel objet Iterator.

Concernant le nommage : TypeScript dispose de types pour Iterable et Iterator, cependant, ces types agissent en quelque sorte comme des "protocoles" pour garantir le bon fonctionnement de certaines opérations. "Cela signifie que toutes les valeurs déclarées Iterable ou Iterator en TypeScript ne disposent pas de ces méthodes.

Mais il existe toujours une nouvelle valeur d'exécution appelée Iterator. Vous pouvez référencer Iterator, ainsi que Iterator.prototype, comme des valeurs réelles en JavaScript. C'est un peu gênant car TypeScript définit déjà sa propre chose appelée Iterator uniquement pour la vérification de type. En raison de ce malheureux conflit de noms, TypeScript doit donc introduire un type distinct pour décrire ces itérateurs natifs/intégrés.

TypeScript 5.6 introduit un nouveau type appelé IteratorObject. Il est défini comme suit :

Code : Sélectionner tout
1
2
3
interface IteratorObject<T, TReturn = unknown, TNext = unknown> extends Iterator<T, TReturn, TNext> {
    [Symbol.iterator](): IteratorObject<T, TReturn, TNext>;
}
De nombreuses collections et méthodes intégrées produisent des sous-types d'IteratorObjects (comme ArrayIterator, SetIterator, MapIterator, etc.), et les types JavaScript et DOM dans lib.d.ts, ainsi que @types/node, ont été mis à jour pour utiliser ce nouveau type.

De même, il existe un type AsyncIteratorObject pour la parité. AsyncIterator n'existe pas encore en tant que valeur d'exécution en JavaScript qui apporte les mêmes méthodes pour AsyncIterables, mais c'est une proposition active et ce nouveau type s'y prépare.

L'option --noCheck

TypeScript 5.6 introduit une nouvelle option de compilation, --noCheck, qui permet d'ignorer la vérification de type pour tous les fichiers d'entrée. Cela permet d'éviter les vérifications de type inutiles lors de l'analyse sémantique nécessaire à l'émission des fichiers de sortie.

Un scénario pour cela est de séparer la génération de fichiers JavaScript de la vérification de type afin que les deux puissent être exécutés comme des phases distinctes. Par exemple, vous pouvez exécuter tsc --noCheck pendant l'itération, puis tsc --noEmit pour une vérification complète du type. Vous pouvez également exécuter les deux tâches en parallèle, même en mode --watch, bien que vous devriez probablement spécifier un chemin --tsBuildInfoFile séparé si vous les exécutez vraiment en même temps.

--noCheck est également utile pour émettre des fichiers de déclaration d'une manière similaire. Dans un projet où --noCheck est spécifié sur un projet conforme à --isolatedDeclarations, TypeScript peut rapidement générer des fichiers de déclaration sans passer par la vérification de type. Les fichiers de déclaration générés s'appuieront uniquement sur des transformations syntaxiques rapides.

Notez que dans les cas où --noCheck est spécifié, mais qu'un projet n'utilise pas --isolatedDeclarations, TypeScript peut toujours effectuer autant de vérifications de type que nécessaire pour générer des fichiers .d.ts. Dans ce sens, --noCheck est un peu mal nommé ; cependant, le processus sera plus paresseux qu'une vérification de type complète, ne calculant que les types des déclarations non annotées. Cela devrait être beaucoup plus rapide qu'une vérification de type complète.

noCheck est également disponible via l'API TypeScript en tant qu'option standard. En interne, transpileModule et transpileDeclaration utilisaient déjà noCheck pour accélérer les choses (au moins à partir de TypeScript 5.5). Désormais, n'importe quel outil de compilation devrait être en mesure de tirer parti de ce drapeau, en adoptant une variété de stratégies personnalisées pour coordonner et accélérer les compilations.

Autoriser --build avec des erreurs intermédiaires

Le concept de références de projet de TypeScript vous permet d'organiser votre base de code en plusieurs projets et de créer des dépendances entre eux. L'exécution du compilateur TypeScript en mode --build (ou tsc -b en abrégé) est le moyen intégré de mener cette compilation à travers les projets et de déterminer quels projets et quels fichiers doivent être compilés.

Auparavant, l'utilisation du mode --build supposait --noEmitOnError et arrêtait immédiatement la compilation en cas d'erreur. Cela signifiait que les projets "en aval" ne pouvaient jamais être vérifiés et compilés si l'une de leurs dépendances "en amont" avait des erreurs de compilation. En théorie, il s'agit d'une approche très cromulante - si un projet a des erreurs, il n'est pas nécessairement dans un état cohérent pour ses dépendances.

En réalité, ce type de rigidité rendait des choses comme les mises à jour pénibles. Par exemple, si le projetB dépend du projetA, les personnes qui connaissent mieux le projetB ne peuvent pas mettre à jour leur code de manière proactive tant que leurs dépendances n'ont pas été mises à jour. Ils sont bloqués par le travail de mise à niveau du projetA en premier lieu.

À partir de TypeScript 5.6, le mode --build continuera à construire des projets même s'il y a des erreurs intermédiaires dans les dépendances. Les erreurs intermédiaires seront signalées de manière cohérente et les fichiers de sortie seront générés au mieux ; cependant, la construction se poursuivra jusqu'à son terme sur le projet spécifié.

Si vous souhaitez arrêter la compilation au premier projet contenant des erreurs, vous pouvez utiliser un nouveau drapeau appelé --stopOnBuildErrors. Cela peut être utile lorsque vous travaillez dans un environnement CI, ou lorsque vous itérez sur un projet qui est fortement dépendant d'autres projets.

Notez que pour ce faire, TypeScript émet toujours un fichier .tsbuildinfo pour tout projet dans une invocation --build (même si --incremental/--composite n'est pas spécifié). Cela permet de garder une trace de l'état de l'invocation de --build et du travail à effectuer dans le futur.

Source : Microsoft

Et vous ?

Quel est votre avis sur cette nouvelle version de TypeScript ?

Voir aussi :

Microsoft annonce la disponibilité de TypeScript 5.5, cette version apporte les prédicats de type inférés, les déclarations isolées, ainsi qu'une amélioration de la fiabilité de l'éditeur

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

TypeScript, les types marqués : Produire un moyen de marquer un type, en fournissant un moyen automatisé et facile à utiliser pour rendre un type nominal, par Prosopo

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Gugelhupf
Modérateur https://www.developpez.com
Le 10/09/2024 à 15:21
Je suis très preneur de ce type d'amélioration, cela nous a permis d'améliorer un code en production:

Avant correction :
Code typescript : Sélectionner tout
.flatMap(attachedProduct => ([attachedProduct?.price] || []));

Après correction :
Code typescript : Sélectionner tout
.flatMap(attachedProduct => attachedProduct.price ? [attachedProduct.price] : []);

que l'on pourrait simplifier par :
Code typescript : Sélectionner tout
.flatMap(attachedProduct => attachedProduct.price || []);

On se sert du flatMap() pour éviter de faire filter()+map(), mais parfois nous allons trop vite dans l'écriture du code et les jeux de données dans nos tests ne suffisent pas à déceler tous les problèmes. Ce fix nous évitera de nous retrouver avec un tableau contenant des éléments undefined
1  0