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 !

TypeScript 3.6 est disponible et apporte le support de import.meta dans SystemJS
Et des API qui prennent en charge --build et --incremental

Le , par Stéphane le calme

41PARTAGES

13  0 
Microsoft a annoncé la disponibilité générale de TypeScript 3.6.

Générateurs plus stricts

TypeScript 3.6 introduit une vérification plus stricte pour les itérateurs et les fonctions du générateur. Dans les versions précédentes, les utilisateurs de générateurs n'avaient aucun moyen de différencier si une valeur était cédée ou renvoyée par un générateur.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
function* foo() {
    if (Math.random() < 0.5) yield 100;
    return "Finished!"
}
 
let iter = foo();
let curr = iter.next();
if (curr.done) {
    // TypeScript 3.5 and prior thought this was a 'string | number'.
    // It should know it's 'string' since 'done' was 'true'!
    curr.value
}

De plus, les générateurs ont simplement supposé que le type de yield était toujours any.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
function* bar() {
    let x: { hello(): void } = yield;
    x.hello();
}
 
let iter = bar();
iter.next();
iter.next(123); // oops! runtime error!

Dans TypeScript 3.6, le vérificateur sait maintenant que le type correct pour curr.value doit être string dans le premier exemple et va correctement afficher une erreur lors de l'appel à next() dans le dernier exemple. En effet, certains changements apportés aux déclarations de type Iterator et IteratorResult pour inclure quelques nouveaux paramètres de type, ainsi qu’à un nouveau type utilisé par TypeScript pour représenter des générateurs appelé type Generator.

Le type Iterator permet désormais aux utilisateurs de spécifier le type généré, le type renvoyé et le type que le type suivant peut accepter.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
interface Iterator<T, TReturn = any, TNext = undefined> {
    // Takes either 0 or 1 arguments - doesn't accept 'undefined'
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return?(value?: TReturn): IteratorResult<T, TReturn>;
    throw?(e?: any): IteratorResult<T, TReturn>;
}

S'appuyant sur ce travail, le nouveau type Generator est un Iterator qui a toujours les méthodes return et throw et qui est également itérable.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
interface Generator<T = unknown, TReturn = any, TNext = unknown>
        extends Iterator<T, TReturn, TNext> {
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return(value: TReturn): IteratorResult<T, TReturn>;
    throw(e: any): IteratorResult<T, TReturn>;
    [Symbol.iterator](): Generator<T, TReturn, TNext>;
}

Pour permettre la différenciation entre les valeurs renvoyées et les valeurs produites, TypeScript 3.6 convertit le type IteratorResult en un type d'union discriminé:

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
 
interface IteratorYieldResult<TYield> {
    done?: false;
    value: TYield;
}
 
interface IteratorReturnResult<TReturn> {
    done: true;
    value: TReturn;
}

En bref, cela signifie que vous pourrez affiner correctement les valeurs des itérateurs en les traitant directement.

Pour représenter correctement les types pouvant être transmis à un générateur à partir d'appels de next(), TypeScript 3.6 déduit également certaines utilisations du rendement dans le corps d'une fonction de générateur.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
function* foo() {
    let x: string = yield;
    console.log(x.toUpperCase());
}
 
let x = foo();
x.next(); // first call to 'next' is always ignored
x.next(42); // error! 'number' is not assignable to 'string'

Si vous préférez être explicite, vous pouvez également appliquer le type de valeurs pouvant être renvoyées, produites et évaluées à partir d'expressions yield à l'aide d'un type de retour explicite. Ci-dessous, next() ne peut être appelé qu'avec boolean et est tributaire des valeurs de done, value est soit un string, soit un number.

Code TypeScript : 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
27
28
29
30
31
32
/**
 * - yields numbers
 * - returns strings
 * - can be passed in booleans
 */
function* counter(): Generator<number, string, boolean> {
    let i = 0;
    while (true) {
        if (yield i++) {
            break;
        }
    }
    return "done!";
}
 
var iter = counter();
var curr = iter.next()
while (!curr.done) {
    console.log(curr.value);
    curr = iter.next(curr.value === 5)
}
console.log(curr.value.toUpperCase());
 
// prints:
//
// 0
// 1
// 2
// 3
// 4
// 5
// DONE!

Amélioration de l'UX autour des Promise

Promise sont l’un des moyens les plus courants de travailler avec des données asynchrones de nos jours. Malheureusement, se servir d'une API orientée Promise peut être déroutant pour les utilisateurs. TypeScript 3.6 apporte des améliorations pour le traitement incorrect des Promise.

Par exemple, il est très courant d’oublier de mettre un .then() ou await aux contenus d’un Promise avant la transmission à une autre fonction. Les messages d’erreur de TypeScript sont maintenant spécialisés et indiquent à l’utilisateur qu’ils devraient peut-être envisager d’utiliser le mot-clé await.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface User {
    name: string;
    age: number;
    location: string;
}
 
declare function getUserData(): Promise<User>;
declare function displayUser(user: User): void;
 
async function f() {
    displayUser(getUserData());
//              ~~~~~~~~~~~~~
// Argument of type 'Promise<User>' is not assignable to parameter of type 'User'.
//   ...
// Did you forget to use 'await'?
}

Il est également courant d’essayer d’accéder à une méthode avant d'utiliser un await ou un .then () sur Promise. C’est un autre exemple parmi tant d’autres où Microsoft planifie de faire mieux.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
async function getCuteAnimals() {
    fetch("https://reddit.com/r/aww.json")
        .json()
    //   ~~~~
    // Property 'json' does not exist on type 'Promise<Response>'.
    //
    // Did you forget to use 'await'?
}

L'objectif est de fournir au moins un contexte plus précis.

Dans le même esprit de simplification de la vie, en dehors de meilleurs messages d’erreur sur Promise, Microsoft propose également des solutions rapides dans certains cas.


Meilleur support Unicode pour les identificateurs

TypeScript 3.6 prend mieux en charge les caractères Unicode dans les identificateurs lors de l’émission vers des cibles ES2015 et ultérieures.

Le support d'import.meta dans SystemJS

TypeScript 3.6 prend en charge la transformation de import.meta en context.meta lorsque la cible de votre module est définie sur système.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// This module:
 
console.log(import.meta.url)
 
// gets turned into the following:
 
System.register([], function (exports, context) {
  return {
    setters: [],
    execute: function () {
      console.log(context.meta.url);
    }
  };
});

Les API prennent en charge --build et --crcremental

TypeScript 3.0 a introduit la prise en charge du référencement d'autres projets et de leur build incrémentielle à l'aide de l'indicateur --build. En outre, TypeScript 3.4 a introduit l'indicateur --incremental pour enregistrer les informations sur les compilations précédentes afin de reconstruire uniquement certains fichiers. Ces drapeaux ont été incroyablement utiles pour structurer les projets de manière plus flexible et accélérer. Malheureusement, l’utilisation de ces indicateurs n’a pas fonctionné avec des outils de construction tiers, tels que Gulp et Webpack. TypeScript 3.6 expose maintenant deux ensembles d'API à utiliser pour les références de projet et la création de programmes incrémentiels.

Pour créer des versions --incremental, les utilisateurs peuvent exploiter les API createIncrementalProgram et createIncrementalCompilerHost. Les utilisateurs peuvent également relancer d'anciennes instances de programmes à partir de fichiers .tsbuildinfo générés par cette API à l'aide de la nouvelle fonction readBuilderProgram, destinée uniquement à être utilisée pour la création de nouveaux programmes (vous ne pouvez pas modifier l'instance renvoyée, cette fonction peut être uniquement utilisée pour le paramètre oldProgram dans d'autres fonctions create * Program).

Pour tirer parti des références de projet, une nouvelle fonction createSolutionBuilder est disponible et renvoie une instance du nouveau type SolutionBuilder.

Source : Microsoft

Voir aussi :

Typescript 3.7.0 va prendre en charge l'opérateur de chaînage d'optionnels (?.) en s'appuyant sur le 3e draft pour JavaScript
Visual Studio Code 1.35 est disponible en téléchargement et apporte de nombreuses améliorations à l'éditeur ainsi qu'un support de TypeScript 3.5.1
Microsoft annonce la disponibilité de TypeScript 3.5 qui apporte une amélioration de la vitesse, et de nombreuses optimisations

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

Contacter le responsable de la rubrique TypeScript

Partenaire : Hébergement Web