Microsoft annonce la disponibilité de TypeScript 2.4
Qui apporte une vérification plus stricte des paramètres de retour

Le , par Stéphane le calme, Chroniqueur Actualités
Expressions dynamiques import ()

Les expressions d'importation dynamique sont une nouvelle fonctionnalité dans ECMAScript qui vous permet de demander de manière asynchrone un module à n'importe quel point arbitraire dans votre programme. Ces modules reviennent en tant que Promises (transformation d'une fonction asynchrone en un objet – au sens JavaScript du terme – afin de faciliter la manipulation de ladite fonction asynchrone) du module lui-même, et peuvent être en mode await dans une fonction asynchrone, ou peuvent recevoir un rappel avec .then.

Ce que cela signifie, en bref, est que vous pouvez importer de façon conditionnelle et paresseuse d'autres modules et bibliothèques pour rendre votre application plus efficace et plus soucieuse des ressources. Par exemple, voici une fonction async qui n'importe qu'une bibliothèque d'utilitaires lorsqu'elle est nécessaire :

Code TypeScript : Sélectionner tout
1
2
3
4
5
async function getZipFile(name: string, files: File[]): Promise<File> {
    const zipUtil = await import('./utils/create-zip-file');
    const zipContents = await zipUtil.getAsBlob(files);
    return new File(zipContents, name);
}

Microsoft indique que nombreux sont les bundlers qui disposent d’un support pour diviser automatiquement les lots de sortie (ou encore le « fractionnement de code ») en fonction de ces expressions import (), alors les ingénieurs proposent d’envisager d'utiliser cette nouvelle fonctionnalité avec la cible module esnext. Notez que cette fonctionnalité ne sera pas effective avec la cible module es2015, car la fonctionnalité est prévue pour ES2018 ou une version ultérieure.

Énumération de chaînes de caractères

Cela fait déjà un moment que TypeScript dispose des types de chaînes littérales, et d’enums depuis sa sortie. Ayant eu le temps de voir comment ces fonctionnalités étaient utilisées, les ingénieurs ont modifié les énumérations dans TypeScript 2.4 pour voir comment ils pourraient travailler ensemble. Cette version de TypeScript permet maintenant aux membres d'énumération de contenir des initialiseurs de chaînes.

Code TypeScript : Sélectionner tout
1
2
3
4
5
enum Colors {
    Red = "RED",
    Green = "GREEN",
    Blue = "BLUE",
}
Les énumérations de chaînes de caractères ont l'avantage d’être beaucoup plus faciles à déboguer et peuvent également décrire les systèmes existants qui utilisent des chaînes. Comme les énumérations numériques et les types littéraires, ces énumérations peuvent également être utilisées comme étiquettes dans des unions discriminées.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum ShapeKind {
    Circle = "circle",
    Square = "square"
}
 
interface Circle {
    kind: ShapeKind.Circle;
    radius: number;
}
 
interface Square {
    kind: ShapeKind.Square;
    sideLength: number;
}
 
type Shape = Circle | Square;

Vérification améliorée des génériques

TypeScript 2.4 comporte des améliorations dans la façon dont les types sont déduits lorsque les génériques entrent en jeu, ainsi qu'une vérification améliorée lors de la relation entre deux types de fonctions génériques.

Types de retour comme cibles d'inférence

TypeScript peut désormais permettre aux types de fluctuer à travers les types de retour dans certains contextes. Cela signifie que vous pouvez décider plus facilement où placer vos types. Par exemple :

Code TypeScript : Sélectionner tout
1
2
3
4
5
function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[] {
    return a => a.map(f);
}
 
const lengths: (a: string[]) => number[] = arrayMap(s => s.length);

Il arrivait que "s" ait besoin d'être explicitement annoté ou son type aurait été déduit comme {}. Bien que les longueurs puissent être laissées sans description dans ce cas, il a été surprenant pour certains utilisateurs que l'information de ce type n'ait pas été utilisée pour déduire le type de s.

Dans TypeScript 2.4, le système de type sait que "s" est une chaîne du type de longueurs, ce qui pourrait mieux répondre à vos choix stylistiques.

Cela signifie également que certaines erreurs seront détectées, puisque TypeScript peut trouver de meilleurs candidats que le type {} par défaut (ce qui est souvent trop permissif).

Code TypeScript : Sélectionner tout
1
2
3
4
let x: Promise<string> = new Promise(resolve => {
    resolve(10);
    //      ~~ Now correctly errors!
});

Vérification plus stricte des fonctions génériques

TypeScript essaie maintenant d'unifier les paramètres de type lors de la comparaison de deux types de signature unique. En conséquence, vous obtiendrez des contrôles plus stricts lors de la relation entre deux signatures génériques qui peuvent détecter certains bogues.

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
type A = <T, U>(x: T, y: U) => [T, U];
type B = <S>(x: S, y: S) => [S, S];
 
function f(a: A, b: B) {
    a = b;  // Error
    b = a;  // Ok
}

Une vérification de paramètres de rappel plus sûr

Lorsque vous vérifiez si deux fonctions sont assignables l'une à l'autre, TypeScript vérifie si leurs paramètres sont bidirectionnellement assignables : Microsoft l’appelle bivariance de paramètres de fonction. Il y a plusieurs raisons à cela, mais elles découlent principalement du caractère structurel de TypeScript et de la façon dont Microsoft a essayé de faire correspondre l'intuition des gens.

D’après son expérience, les utilisateurs ne se heurtent généralement pas à des problèmes avec tout cela. Cependant, Microsoft a observé que ce modèle s'effondre face à des conteneurs qui ont transmis des données internes via des rappels – en particulier des Promises. Par exemple, Promise <Animal> était assignable à Promise <Chien>, ce qui est incorrect. Vous pouvez voir un comportement similaire dans l'exemple suivant :

Code TypeScript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
interface Animal { animalStuff: any }
interface Dog extends Animal { bark(): void }
 
interface BasicCollection<T> {
    forEach(callback: (value: T) => void): void;
}
 
declare let animalCollection: BasicCollection<Animal>;
declare let dogCollection: BasicCollection<Dog>;
 
// Ceci devrait être une erreur, mais jusqu’à TypeScript 2.3, le langage le permet
.
dogCollection = animalCollection;

Pour résoudre ce problème, TypeScript 2.4 resserre désormais les choses et compare les paramètres qui sont notamment les rappels. Lors de la vérification des rappels, TypeScript sera strict quant à la vérification des paramètres de façon contravariante par rapport à la vérification actuelle. La bivarité des paramètres s'applique toujours autrement, mais Microsoft a constaté que c'était une vérification de sécurité efficace sans changer radicalement le système de type.

Source : Microsoft

Et vous ?

Quelles fonctionnalités vous intéressent le plus ?

Voir aussi :

Comprendre les Promises en JavaScript / TypeScript, article de yahiko
TypeScript entre dans le top 20 des langages les plus populaires, d'après le classement Redmonk de juin 2017
Après avoir réécrit Angular en TypeScript, Google approuve le surensemble JavaScript de Microsoft pour ses développements internes


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Offres d'emploi IT
Gestionnaire de processus ITIL H/F
Sogeti France - Poitou Charentes - Niort (79000)
Architecte développeur symfony senior (projets nationaux)
Linagora - Ile de France - Puteaux (92800)
Recherche alter ego/associé(e)
myHerakles.fr - France - Paris (75000)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique Accueil