TypeScript 3.9 erfüllt Versprechen, aber verschiebt Erwartungen
Die Programmiersprache verbessert den Umgang von Promise.all, aber der geplante awaited-Operator hat es nicht ins Release geschafft.
- Rainald Menge-Sonnentag
Nach einer knapp zweimonatigen Betaphase ist nun TypeScript 3.9 erschienen. Das Release bringt vor allem Verbesserungen im Umgang mit Promise.all
und erkennt undefinierte Funktionen nicht nur bei if
-Bedingungen, sondern auch bei bedingten Operatoren. Außerdem unterdrückt ein neuer Kommentar erwartete Fehlermeldungen.
Hinsichtlich einer Erwartung bleibt das Release wie bereits beim Veröffentlichen der Beta angekündigt jedoch zurück: Der awaited
-Operator war ursprünglich für das aktuelle Release geplant. Er soll ebenso funktionieren wie das Promise
-Unwrapping in JavaScript. Offensichtlich ist die Implementierung jedoch komplizierter als erwartet, sodass die Entwickler sie vorerst auf ein späteres Release verschoben haben.
Vollmundiges Versprechen
Microsoft hatte mit TypeScript 3.7 Methoden wie Promise.all (iterable)
ergänzt, die einen einfachen Weg bieten, für asynchronen Code mehrere Promise
-Bedingungen zu verknüpfen. Das Iterable-Objekt definiert eine Reihe von Versprechen, und wenn alle davon erfüllt sind, gelten die Ansprüche von Promise.all (iterable)
als erfüllt (fullfilled
). Sobald jedoch das erste Versprechen im Interable abgelehnt wird, gilt auch das gesamte Paket als abgelehnt (rejected
).
In den jüngsten Releases kam es jedoch zu Problemen, wenn das Iterable Objekte nulll
oder undefined
enthält, auch wenn die undefinierten Werte keinen Einfluss auf die Bedingung beziehungsweise den Programmverlauf haben wie in folgendem Beispiel aus dem TypeScript-Blog:
interface Lion {
roar(): void
}
interface Seal {
singKissFromARose(): void
}
async function visitZoo(lionExhibit: Promise<Lion>,
sealExhibit: Promise<Seal | undefined>) {
let [lion, seal] = await Promise.all([lionExhibit, sealExhibit]);
lion.roar();
// ~~~~
// Object is possibly 'undefined'.
}
Der Kommentar zeigt die Fehlermeldung, die an der Stelle jedoch falsch ist. Offensichtlich hat der undefinierte Seehund-Part aufgrund einer internen Regression von TypeScript dem Löwen die Zähne gezogen. TypeScript 3.9 behebt das Problem, und Entwickler, die seit Version 3.7 ähnlich nicht nachvollziehbare Fehlermeldungen in dem Zusammenhang erhalten, sollten ihren Code mit dem aktuellen Release erneut kompilieren.
Der Fehler ist zu erwarten
Ein neuer Kommentar unterdrückt Fehlermeldungen, die nicht unerwartet kommen. // @ts-expect-error
eignet sich unter anderem für Unit-Tests, die bestimmte Fehler unabhängig vom TypeScript-Compiler aufspüren sollen. Ein weiterer Einsatzbereich sind Methoden beispielsweise in Librarys, die mit dem aktuellen Code nicht kompatibel sind, sich aber bis zum Release ändern sollen.
Auf den ersten Blick wirkt der neue Kommentar wie eine Doublette des vorhandenen // @ts-ignore
, der ebenfalls Fehlermeldungen unterdrückt. Der entscheidende Unterschied ist, dass // @ts-expect-error
einen Fehler auslöst, wenn er überflüssig ist, also in der folgenden Zeile kein Fehler auftreten kann.
Das ist kein Funktionsaufruf
TypeScript findet seit Version 3.7 vermeintliche Funktionsaufrufe, die aber aufgrund fehlender Klammern keine sind. Folgende Bedingung
if (hasPermission) { ... }
fragt somit nicht wie wohl gedacht den Rückgabewert einer Funktion ab, die Berechtigungen überprüfen soll, sondern prüft lediglich, ob die Funktion hasPermission
definiert ist. Das Ergebnis true
sagt somit nichts über die vermeintlich geprüften Voraussetzungen aus.
Ab TypeScript 3.9 findet die Überprüfung auf solche potenziell folgenschweren Flüchtigkeitsfehler nicht nur für if
-Statements, sondern auch beim bedingten beziehungsweise ternären Operator statt. Sie würde also ebenfalls bei hasPermission ? ...
anschlagen.
Unter der Haube
Des Weiteren hat Microsoft einige Optimierungen zugunsten der Performance vorgenommen. Davon profitieren Pakete wie material-ui
und styled-components
wohl besonders. Für die Arbeit mit Visual Studio Code hat das Team zudem das Überprüfen betroffener import-Anweisungen optimiert.
Weitere Details lassen sich dem TypeScript-Blog entnehmen. Wer die Beta testen möchte, kann sie von NuGet herunterladen oder über npm mit dem Befehl npm install typescript
installieren.
(rme)