Annonce de TypeScript 3.3 RC

Aujourd'hui, nous sommes heureux d'annoncer la disponibilité de notre version candidate (RC) de TypeScript 3.3. Notre espoir est de recueillir les commentaires et les premiers problèmes pour garantir que notre version finale est simple à récupérer et à utiliser immédiatement.

Original dans le blog

Pour commencer à utiliser le RC, vous pouvez l'obtenir via NuGet ou utiliser npm avec la commande suivante:


npm install -g typescript@rc 

Vous pouvez également obtenir le support de l'éditeur en



TypeScript 3.3 devrait être une version fluide à adopter et ne contient aucune modification de rupture. Explorons les nouveautés de la 3.3.


Comportement amélioré pour appeler des types d'union


Lorsque TypeScript a un type d'union A | B A | B , il vous permet d'accéder à toutes les propriétés communes à A et B (c'est-à-dire l'intersection des membres).


 interface A { aProp: string; commonProp: string; } interface B { bProp: number; commonProp: number } type Union = A | B; declare let x: Union; x.aProp; // error - 'B' doesn't have the property 'aProp' x.bProp; // error - 'A' doesn't have the property 'bProp' x.commonProp; // okay! Both 'A' and 'B' have a property named `commonProp`. 

Ce comportement doit être intuitif - vous ne pouvez obtenir une propriété d'un type d'union que si elle est connue pour être dans chaque type d'union.


Qu'en est-il, au lieu d'accéder aux propriétés, nous avons affaire à des types d'appel? Eh bien, lorsque chaque type a exactement une signature avec des paramètres identiques, les choses fonctionnent et vous pouvez appeler ces types.


 type CallableA = (x: boolean) => string; type CallableB = (x: boolean) => number; type CallableUnion = CallableA | CallableB; declare let f: CallableUnion; let x = f(true); // Okay! Returns a 'string | number'. 

Cependant, cette restriction était parfois, eh bien, trop restrictive.


 type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number; // eats and ranks the fruit type ColorConsumer = (color: Color) => string; // consumes and describes the colors declare let f: FruitEater | ColorConsumer; // Cannot invoke an expression whose type lacks a call signature. // Type 'FruitEater | ColorConsumer' has no compatible call signatures.ts(2349) f("orange"); 

Exemple idiot et mauvais message d'erreur mis à part, les FruitEater et les ColorConsumer devraient pouvoir prendre la chaîne "orange" et renvoyer un number ou une string .


Dans TypeScript 3.3, ce n'est plus une erreur.


 type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number; // eats and ranks the fruit type ColorConsumer = (color: Color) => string; // consumes and describes the colors declare let f: FruitEater | ColorConsumer; f("orange"); // It works! Returns a 'number | string'. f("apple"); // error - Argument of type '"apple"' is not assignable to parameter of type '"orange"'. f("red"); // error - Argument of type '"red"' is not assignable to parameter of type '"orange"'. 

Dans TypeScript 3.3, les paramètres de ces signatures sont intersectés ensemble pour créer une nouvelle signature. Dans l'exemple ci-dessus, les paramètres fruit et color sont intersectés ensemble avec un nouveau paramètre de type Fruit & Color . Fruit & Color est vraiment identique à ("apple" | "orange") & ("red" | "orange") qui est équivalent à ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") . Chacune de ces intersections impossibles s'évapore, et nous nous retrouvons avec "orange" & "orange" qui est juste "orange" .


Il reste cependant quelques restrictions. Ce nouveau comportement ne se déclenche que si au plus un type dans l'union a plusieurs surcharges et au plus un type dans l'union a une signature générique. Cela signifie des méthodes sur le number[] | string[] number[] | string[] comme map (qui est générique) ne pourra toujours pas être appelée.


D'un autre côté, des méthodes comme forEach seront désormais appelables, mais sous noImplicitAny il peut y avoir des problèmes.


 interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach(animal => { // ~~~~~~ error! // Parameter 'animal' implicitly has an 'any' type. }); 

Alors que nous continuerons d'améliorer l'expérience ici, cela est strictement plus performant dans TypeScript 3.3, et l'ajout d'une annotation de type explicite fonctionnera.


 interface Dog { kind: "pupper" dogProp: any; } interface Cat { kind: "kittyface" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach((animal: Dog | Cat) => { if (animal.kind === "pupper") { animal.dogProp; // ... } else if (animal.kind === "kittyface") { animal.catProp; // ... } }); 

--build --watch incrémentielle des fichiers pour les projets composites dans --build --watch


Dans TypeScript 3.0, nous avons introduit une nouvelle fonctionnalité de structuration des builds appelée «projets composites». Une partie de l'objectif ici était de s'assurer que les utilisateurs pouvaient diviser les grands projets en parties plus petites qui se construisent rapidement et préservent la structure du projet, sans compromettre l'expérience TypeScript existante. Grâce aux projets composites, TypeScript peut utiliser le mode --build pour recompiler uniquement l'ensemble des projets et des dépendances. Vous pouvez considérer cela comme une optimisation des builds inter- projets.


Cependant, vers l'année dernière, notre équipe a également livré des --watch optimisées --watch mode --watch via une nouvelle API incrémentielle «constructeur». Dans le même esprit, l'idée est que ce mode ne fait que revérifier et réémettre les fichiers modifiés ou les fichiers dont les dépendances peuvent avoir un impact sur la vérification de type. Vous pouvez considérer cela comme une optimisation des builds intra- projet.


--build --watch , la construction de projets composites à l'aide de --build --watch en fait pas cette infrastructure. Une mise à jour dans un projet sous le mode --build --watch forcerait une construction complète de ce projet, plutôt que de déterminer quels fichiers de ce projet étaient affectés.


Dans TypeScript 3.3, l' --build mode --watch exploite également la surveillance incrémentielle des fichiers. Cela peut signifier des builds significativement plus rapides sous --build --watch . Lors de nos tests, cette fonctionnalité a entraîné une réduction de 50% à 75% des temps de construction des temps de --build --watch origine. Vous pouvez en savoir plus sur la demande d'extraction d'origine pour le changement afin de voir des nombres spécifiques, mais nous pensons que la plupart des utilisateurs de projets composites verront des gains importants ici.


Et ensuite?


Au-delà de 3.3, vous pouvez garder un œil sur notre page Feuille de route pour tout travail à venir.


Mais pour le moment, nous avons hâte de connaître votre expérience avec le RC, alors essayez-le maintenant et faites-nous part de vos réflexions!


- Daniel Rosenwasser et l'équipe TypeScript

Source: https://habr.com/ru/post/fr437652/


All Articles