Programmiersprache TypeScript 4.7 verarbeitet ECMAScript-Module
Die Beta enthält neben der ursprünglich bereits für TypeScript 4.5 geplanten Anbindung an ESM eine erweiterte Kontrollflussanalyse für berechnete Properties.
(Bild: pixabay.com/Laszlo Zakarias, gemeinfrei)
Microsoft hat turnusgemäß die erste Beta von TypeScript 4.7 veröffentlicht. Das Release des JavaScript-Superset bringt die ursprünglich bereits vor einem halben Jahr geplante Anbindung an ECMAScript Modules mit. Damit verbunden sind einige zusätzliche Einstellungen und Dateiendungen. Hinsichtlich der Programmiersprache selbst hat die aktuelle Version unter anderem Feinschliff für die Typinferenz über Kontrollflussanalyse und eine Ergänzung für Generics an Bord.
Flexiblere Module
Node.js hat in den letzten Jahren ECMAScript Modules (ESM) neben dem traditionellen Modulsystem CommonJS (CJS) eingefĂĽhrt und maĂźgeblich in Version 12 umgesetzt. FĂĽr TypeScript war die Integration von ESM ursprĂĽnglich bereits in Version 4.5 geplant, fehlte aber schlieĂźlich doch im Release. Als Grund nannte das Team vor allem Bedenken hinsichtlich der Usability, da der neue Modus mehr Verwirrung stiften als Nutzen bringen wĂĽrde. In der Zwischenzeit hat es Feedback gesammelt und sieht die Programmiersprache nun als reif fĂĽr die Umstellung an.
Videos by heise
TypeScript 4.7 soll die Integration jetzt in leicht erweiterter Form umsetzen. Zum Aktivieren fĂĽhrt das Release unter den compilerOptions wie bereits fĂĽr TypeScript 4.5 geplant die module-Einstellungen node12 und nodenext ein, um die Anbindung an ECMAScript Modules zu aktivieren.
Node kennt für die Datei package.json die Konfiguration "type". Dabei legt "module" das Zusammenspiel mit ESM fest, während "commonjs" für das ältere System steht. Erstere Einstellung erlaubt unter anderem import- und export-Anweisungen, und relative Importe benötigen anders als bei CJS die jeweilige Dateiendung wie ".js".
TypeScript untersucht für .ts-., .tsx-., .js-. oder .jsx-Dateien die zugehörige package.json, ob die Datei ein ES-Modul ist. Daraus ermittelt das System zum einen, wie es andere Module findet, die die Datei importiert. Beim Kompilieren von .ts-Dateien als ES-Modul fasst der Compiler zudem die import- und export-Anweisungen nicht an.
Zusätzliche Dateiendungen und Konfigurationen
Für die benötigten Endungen in relativen Importen müssen Entwicklerinnen und Entwickler ihren Code anpassen, allerdings nehmen Auto-Importe und Pfadvervollständigung ihnen die Arbeit laut dem Blogbeitrag zur Beta von TypeScript 4.7 weitgehend ab.
Für die explizite Angabe des Modulsystems im Namen kennt Node.js die Endungen .mjs für ES-Module und .cjs für CommonJS Module. Analog dazu führt TypeScript .mts und .cts an, die es beim Übertragen in JavaScript-Dateien in .mjs und .cjs umwandelt. Für Deklarationen gibt es zusätzlich die Dateiendungen .d.mts und .d.cts.
ESM bringt einige grundlegende Änderungen beim Ausführen von JavaScript-Code mit sich und benötigt unter anderem definierte Moduleintrittspunkte. TypeScript sucht in Dateien nach import- und export-Anweisungen, um sie als Modul zu identifizieren. Dieses Vorgehen lässt sich in TypeScript 4.7 mit der neuen Konfiguration moduleDetection manuell überschreiben. "legacy" prüft weiterhin über import und export. "auto" ist die Standardeinstellung und testet zusätzlich unter anderem, ob das "type"-Feld in package.json auf "module" gesetzt ist. Unter "force" behandelt TypeScript jede Datei außer den Deklarationen als Modul.
Jenseits des Modulsystems
Neben dem Zusammenspiel mit dem Modulsystem bringt TypeScript 4.7 einige Änderungen an der Sprache mit, die allerdings vor allem unter der Haube liegen. Unter anderem erweitert das Release die Kontrollflussanalyse, um den Typ berechneter Properties korrekt zu erkennen. Folgender Beispielcode aus dem TypeScript-Blog löst unter TypeScript 4.6 eine Fehlermeldung aus:
const key = Symbol();
const numberOrString = Math.random() < 0.5 ? 42 : "hello";
let obj = {
[key]: numberOrString,
};
if (typeof obj[key] === "string") {
let str = obj[key].toUpperCase();
}
Grund dafĂĽr ist, dass TypeScript fĂĽr die Typinferenz nur die Deklaration von numberOrString nutzt, womit es wahlweise eine Zahl oder eine Zeichenkette sein kann. TypeScript 4.7 erkennt nun, dass aufgrund des strikten Gleichheitsoperators === der Typ von obj[key] innerhalb des Blocks string sein muss.
Nennenswert ist zudem eine Ergänzung für Generics, die eine direkte Zuweisung für einen bestimmten Typen erlaubt. Als Beispiel führt der Blogbeitrag folgendes Interface an:
interface Box<T> {
value: T;
}
function makeBox<T>(value: T) {
return { value };
}
Mit einer neuen Syntax lässt sich sowohl aus dem Konstruktor als auch aus dem Funktionsaufruf eine spezielle Variante anlegen, die lediglich beispielsweise string-Objekte akzeptiert:
const makeStringBox = makeBox<string>;
// TypeScript akzeptiert keine andere Zuweisung als string
// Folgende Zeile l�st daher einen Fehler aus:
makeStringBox(42);
Die Syntax lässt sich auch für Collections wie Array, Map und Set verwenden:
const ErrorMap = Map<string, Error>;
const errorMap = new ErrorMap();
Weitere Neuerungen in TypeScript 4.7 wie die erweiterte Funktionsinferenz für Objekte und Methoden lassen sich dem TypeScript-Blog entnehmen. Die Betaphase ist wie üblich auf gut sechs Wochen ausgelegt, und das endgültige Release soll laut Roadmap am 24. Mai erscheinen. Die ausführliche Diskussion zur Integration des Modulsystems ECMAScript Modules findet sich im zugehörigen Pull Request.
Siehe auch:
- TypeScript bei heise Download
(rme)