Ankündigung von TypeScript 3.3 RC

Heute freuen wir uns, die Verfügbarkeit unseres Release Candidate (RC) von TypeScript 3.3 bekannt zu geben. Wir hoffen, Feedback und frühe Ausgaben zu sammeln, um sicherzustellen, dass unsere endgültige Version einfach zu erfassen und sofort zu verwenden ist.

Original im Blog

Um mit der Verwendung des RC zu beginnen, können Sie ihn über NuGet herunterladen oder npm mit dem folgenden Befehl verwenden:


npm install -g typescript@rc 

Sie können auch Editor-Unterstützung von erhalten



TypeScript 3.3 sollte eine reibungslose Version sein und keine wesentlichen Änderungen enthalten. Lassen Sie uns untersuchen, was in 3.3 neu ist.


Verbessertes Verhalten beim Aufrufen von Unionstypen


Wenn TypeScript eine Vereinigung hat, geben Sie A | B A | B ermöglicht es Ihnen, auf alle Eigenschaften zuzugreifen, die sowohl A als auch B (d. H. Den Schnittpunkt von Elementen).


 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`. 

Dieses Verhalten sollte sich intuitiv anfühlen. Sie können eine Eigenschaft eines Unionstyps nur dann abrufen, wenn bekannt ist, dass sie in jedem Unionstyp vorhanden ist.


Was ist mit dem Aufruf von Typen, anstatt auf Eigenschaften zuzugreifen? Wenn jeder Typ genau eine Signatur mit identischen Parametern hat, funktionieren die Dinge einfach und Sie können diese Typen aufrufen.


 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'. 

Diese Einschränkung war jedoch manchmal zu restriktiv.


 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"); 

Abgesehen von einem dummen Beispiel und einer schlechten Fehlermeldung sollten sowohl FruitEater als auch FruitEater in der Lage sein, die Zeichenfolge "orange" zu nehmen und entweder eine number oder eine string .


In TypeScript 3.3 ist dies kein Fehler mehr.


 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"'. 

In TypeScript 3.3 werden die Parameter dieser Signaturen zusammengeschnitten, um eine neue Signatur zu erstellen. Im obigen Beispiel werden die Parameter fruit und color zusammen mit einem neuen Parameter vom Typ Fruit & Color geschnitten. Fruit & Color ist wirklich dasselbe wie ("apple" | "orange") & ("red" | "orange") was ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") ("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange") . Jede dieser unmöglichen Kreuzungen verdunstet und wir haben "orange" & "orange" was nur "orange" .


Es gibt jedoch noch einige Einschränkungen. Dieses neue Verhalten tritt nur ein, wenn höchstens ein Typ in der Union mehrere Überladungen aufweist und höchstens ein Typ in der Union eine generische Signatur hat. Das heißt Methoden auf number[] | string[] number[] | string[] like map (generisch) kann immer noch nicht aufgerufen werden.


Auf der anderen Seite können Methoden wie forEach jetzt noImplicitAny werden, aber unter noImplicitAny können einige Probleme auftreten.


 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. }); 

Während wir die Erfahrung hier weiter verbessern werden, ist dies in TypeScript 3.3 strikt besser möglich, und das Hinzufügen einer expliziten Typanmerkung funktioniert.


 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; // ... } }); 

Inkrementelle Dateiüberwachung für zusammengesetzte Projekte in --build --watch


In TypeScript 3.0 haben wir eine neue Funktion zum Strukturieren von Builds eingeführt, die als "zusammengesetzte Projekte" bezeichnet wird. Ein Teil des Ziels bestand darin, sicherzustellen, dass Benutzer große Projekte in kleinere Teile aufteilen können, die schnell erstellt werden und die Projektstruktur beibehalten, ohne die vorhandene TypeScript-Erfahrung zu beeinträchtigen. Dank zusammengesetzter Projekte kann TypeScript im --build Modus nur die Gruppe von Projekten und Abhängigkeiten neu kompilieren. Sie können sich dies als Optimierung der projektübergreifenden Builds vorstellen.


Um das letzte Jahr herum hat unser Team jedoch auch optimierte Builds für den --watch Modus über eine neue inkrementelle Builder-API ausgeliefert. In ähnlicher Weise besteht die gesamte Idee darin, dass in diesem Modus nur geänderte Dateien oder Dateien, deren Abhängigkeiten sich auf die Typprüfung auswirken können, erneut überprüft und erneut ausgegeben werden. Sie können sich dies als Optimierung der projektinternen Builds vorstellen.


--build --watch Verbundprojekten mit --build --watch diese Infrastruktur tatsächlich nicht genutzt. Ein Update in einem Projekt im Modus --build --watch würde einen vollständigen Build dieses Projekts erzwingen, anstatt zu bestimmen, welche Dateien in diesem Projekt betroffen sind.


In TypeScript 3.3 --build das Flag --build des --build Modus auch die inkrementelle Dateiüberwachung. Das kann bedeuten, dass Builds unter --build --watch deutlich schneller --build --watch . In unseren Tests hat diese Funktionalität zu einer Reduzierung der Build-Zeiten um 50% bis 75% gegenüber den ursprünglichen --build --watch Zeiten geführt. Sie können mehr über die ursprüngliche Pull-Anfrage für die Änderung lesen , um bestimmte Zahlen zu sehen, aber wir glauben, dass die meisten Benutzer von zusammengesetzten Projekten hier signifikante Gewinne sehen werden.


Was kommt als nächstes?


Ab 3.3 können Sie unsere Roadmap-Seite für alle anstehenden Arbeiten im Auge behalten.


Aber jetzt freuen wir uns darauf, von Ihren Erfahrungen mit dem RC zu hören. Probieren Sie es jetzt aus und teilen Sie uns Ihre Gedanken mit!


- Daniel Rosenwasser und das TypeScript-Team

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


All Articles