TypeScript 6.0 angekündigt
(devblogs.microsoft.com)- Das letzte Release auf Basis der aktuellen JavaScript-Codebasis und ein Bridging-Release, das den Übergang zu TypeScript 7.0 vorbereitet, dem in Go geschriebenen nativen Port
- Enthält Verbesserungen bei Typherleitung und Modulauflösung, darunter reduzierte Kontextsitivität für Funktionen ohne Verwendung von
thissowie Unterstützung für Subpath Imports mit Präfix#/ - Umfassende Modernisierung der Standardwerte der Compiler-Optionen, darunter
strictstandardmäßigtrue,targetstandardmäßiges2025undtypesstandardmäßig[] - Breite Deprecation von Legacy-Optionen, darunter ES5-Target, AMD/UMD/SystemJS-Module,
--baseUrl,--moduleResolution node10usw. - Zusätzliche Typunterstützung für aktuelle ECMAScript-Stage-4-Vorschläge wie Temporal API,
getOrInsert/getOrInsertComputedfür Map undRegExp.escape
Die Position von TypeScript 6.0
- Das letzte Release auf Basis der aktuellen JavaScript-Codebasis, das als Brücke für den Übergang zu TypeScript 7.0 (nativer Go-Port) dient
- TypeScript 7.0 nutzt nativen Code und Shared-Memory-Multithreading und ist bereits sehr nah an der Fertigstellung
- Die meisten Änderungen in 6.0 dienen dazu, die Einführung von 7.0 auszurichten und vorzubereiten
- TypeScript 7.0 kann vorab über die VS Code-Erweiterung oder das npm-Paket ausprobiert werden
Änderungen seit Beta und RC
- Angepasstes Type-Checking von Funktionsausdrücken bei generischen Aufrufen (insbesondere generischen JSX-Ausdrücken) — erkennt mehr Bugs in bestehendem Code, kann aber bei einigen generischen Aufrufen explizite Typargumente erforderlich machen
- Die Ausweitung der Deprecation der Import-Assertion-Syntax (
assert) gilt jetzt auch fürimport()-Aufrufe - Aktualisierte DOM-Typen — spiegeln aktuelle Webstandards wider, inklusive Anpassungen rund um die Temporal API
Reduzierte Kontextsitivität für Funktionen ohne Verwendung von this
- TypeScript klassifiziert bei der Typherleitung Funktionen mit Parametern ohne expliziten Typ als kontextsensitive Funktionen (contextually sensitive functions) und behandelt sie in der Inferenzreihenfolge nachrangig
- Funktionen in Methodensyntax hatten wegen des impliziten
this-Parameters anders als Arrow Functions bislang immer den Status „kontextsensitiv“- Dadurch konnte die Typherleitung je nach Reihenfolge von Methoden in Objektliteralen fehlschlagen
- In TypeScript 6.0 gelten Funktionen, die
thistatsächlich nicht verwenden, nicht mehr als kontextsensitiv- Diese Funktionen erhalten bei der Typherleitung höhere Priorität, sodass die Inferenz unabhängig von der Methodenreihenfolge korrekt funktioniert
- Implementiert durch einen Beitrag von Mateusz Burzyński
Unterstützung für Subpath Imports mit Präfix #/
- Die Subpath-Imports-Funktion von Node.js definiert Aliasse für interne Module eines Pakets über das Feld
importsinpackage.json - Bisher musste auf
#zwingend ein Zeichen folgen, sodass Pfade mit Präfix#/nicht nutzbar waren- Das sorgte bei Entwicklern, die aus Bundlern die Präfix-Konvention
@/gewohnt sind, für Verwirrung
- Das sorgte bei Entwicklern, die aus Bundlern die Präfix-Konvention
- Node.js hat vor Kurzem damit begonnen, Subpath Imports mit Präfix
#/zu unterstützen- Damit sind kompakte Mappings in der Form
"#/*": "./dist/*"möglich
- Damit sind kompakte Mappings in der Form
- TypeScript 6.0 unterstützt dies mit den Optionen
--moduleResolution nodenextundbundler - Implementiert durch einen Beitrag von magic-akari
Kombination aus --moduleResolution bundler und --module commonjs erlaubt
- Bisher war
--moduleResolution bundlernur mit--module esnextoder--module preservenutzbar - Durch die Deprecation von
--moduleResolution node(node10) ist diese neue Kombination für viele Projekte der passendste Upgrade-Pfad - Langfristig wird die Migration zu
--module preserve+--moduleResolution bundleroder zu--module nodenextempfohlen
Das Flag --stableTypeOrdering
- Die Type-IDs, die TypeScript intern Typen zuweist, werden von der Verarbeitungsreihenfolge bestimmt und dienen als Grundlage für die Sortierung von Union-Typen
- Dadurch kann es zu unvorhersehbaren Effekten kommen, bei denen sich das Ergebnis des Declaration Emit je nach Deklarationsreihenfolge verändert
- TypeScript 7.0 führt paralleles Type-Checking ein und verwendet zur Lösung des Problems nichtdeterministischer ID-Zuweisungen einen deterministischen, inhaltsbasierten Sortieralgorithmus
- Beispiel:
100 | 500wird immer in derselben Reihenfolge ausgegeben
- Beispiel:
- Wenn das Flag
--stableTypeOrderingin 6.0 aktiviert wird, entspricht das Typ-Sortierverhalten dem von 7.0, wodurch Unterschiede zwischen beiden Codebasen reduziert werden- Möglich ist dabei ein Leistungsverlust von bis zu 25 % beim Type-Checking
- Typfehler durch Unterschiede bei der Inferenz lassen sich durch explizite Typargumente oder Variablenannotationen beheben
- Das Flag ist nur für Migrationsdiagnosen von 6.0 auf 7.0 gedacht und nicht für den dauerhaften Einsatz empfohlen
Die Option es2025 (target und lib)
- ES2025 enthält keine neuen JavaScript-Sprachfeatures, fügt aber Typen für Built-in-APIs hinzu, etwa
RegExp.escape Promise.try,Iterator-Methoden undSet-Methoden, die zuvor inesnextlagen, wurden naches2025verschoben- Implementiert durch einen Beitrag von Kenta Moriuchi
Typunterstützung für die Temporal API
- TypeScript 6.0 enthält die Built-in-Typen des Temporal-Vorschlags, der Stage 4 erreicht hat
- Nutzbar mit
--target esnextoder"lib": ["esnext"](oder dem feinerenesnext.temporal) - APIs wie
Temporal.Now.instant().subtract()und.add()können typsicher verwendet werden - Die API ist bereits in mehreren Laufzeitumgebungen verfügbar und als Stage 4 offizieller Teil der JavaScript-Sprache
- Implementiert durch einen Beitrag von Renegade334
Typunterstützung für die „upsert“-Methoden von Map (getOrInsert / getOrInsertComputed)
- Vereinfacht das wiederkehrende Muster, bei einer Map die Existenz eines Schlüssels zu prüfen und bei Bedarf einen Standardwert zu setzen
- Der ECMAScript-„upsert“-Vorschlag hat Stage 4 erreicht und fügt
MapundWeakMapzwei neue Methoden hinzugetOrInsert: Fügt bei fehlendem Schlüssel den angegebenen Standardwert ein und gibt ihn zurückgetOrInsertComputed: Berechnet den Standardwert per Callback verzögert, wenn dessen Erzeugung teuer ist- Der Callback erhält den Schlüssel als Argument und kann so auch für schlüsselbasierte Standardwerte genutzt werden
- Wurde zu
esnextlibhinzugefügt und ist in TypeScript 6.0 sofort nutzbar - Implementiert durch einen Beitrag von Renegade334
RegExp.escape
- Die Funktion
RegExp.escapezum Escapen von Sonderzeichen in regulären Ausdrücken hat Stage 4 erreicht - Ist in
es2025libenthalten und in TypeScript 6.0 verfügbar - Implementiert durch einen Beitrag von Kenta Moriuchi
Integration von dom.iterable und dom.asynciterable in dom lib
- Bisher musste für Iteration über
NodeList,HTMLCollectionusw. explizit"lib": ["dom", "dom.iterable"]angegeben werden - In TypeScript 6.0 wurden die Inhalte von
lib.dom.iterable.d.tsundlib.dom.asynciterable.d.tsvollständig inlib.dom.d.tsintegriertdom.iterableunddom.asynciterablekönnen weiter referenziert werden, sind aber leere Dateien
- Da alle großen modernen Browser diese Funktionen unterstützen, ist das eine Komfortverbesserung, die eine häufige Fehlerquelle beseitigt
Wichtige Änderungen bei Standardwerten
strictstandardmäßigtrue: Da die meisten neuen Projekte den Strict Mode wollen, müssen Projekte, die bisher auffalseangewiesen waren, explizit"strict": falsesetzenmodulestandardmäßigesnext: Spiegelt wider, dass ESM zum dominierenden Modulformat geworden isttargetstandardmäßig aktuelle ES-Version (derzeites2025): Da Evergreen-Runtimes üblich sind, ist Transpilation auf alte Versionen meist unnötignoUncheckedSideEffectImportsstandardmäßigtrue: Hilft dabei, Tippfehler in Imports nur für Side Effects zu erkennenlibReplacementstandardmäßigfalse: Verbessert die Standard-Performance, indem unnötige Fehler bei der Modulauflösung und zusätzliche Watch-Ziele vermieden werden
Standardwert von rootDir auf . geändert
- Bisher wurde bei fehlender Angabe das gemeinsame Verzeichnis aller nicht deklarierten Eingabedateien hergeleitet
- Um festzustellen, ob eine Datei zu einem Projekt gehört, musste dieses Projekt geladen und geparst werden
- In TypeScript 6.0 ist der Standardwert fest auf das Verzeichnis von
tsconfig.jsongesetzt - Liegen Quelldateien tiefer als
tsconfig.json, muss z. B."rootDir": "./src"explizit gesetzt werden- Andernfalls kann eine unbeabsichtigte Ausgabestruktur wie
./dist/src/index.jsentstehen
- Andernfalls kann eine unbeabsichtigte Ausgabestruktur wie
Standardwert von types auf [] geändert
- Bisher wurden alle Pakete in
node_modules/@typesautomatisch eingebunden, was beim Build zu großem Overhead führte- In typischen Repositories werden oft Hunderte
@types-Pakete transitiv einbezogen
- In typischen Repositories werden oft Hunderte
- TypeScript 6.0 ändert den Standardwert auf
[](leeres Array) und verhindert so das Laden unnötiger Deklarationsdateien - In der Praxis wurden Build-Zeit-Verbesserungen von 20 bis 50 % beobachtet
- Die meisten Projekte benötigen nun eine explizite Konfiguration wie
"types": ["node"]oder"types": ["node", "jest"]- Mit
"types": ["*"]kann das bisherige Verhalten wiederhergestellt werden
- Mit
Deprecation-Punkte
target: es5 deprecated
- Das ES5-Target hat wegen des Endes von IE und der Verbreitung von Evergreen-Browsern kaum noch Anwendungsfälle
- Das Mindest-Target wird auf ES2015 angehoben; falls ES5-Ausgabe nötig ist, wird ein externer Compiler empfohlen
--downlevelIteration deprecated
- Hatte nur beim ES5-Emit Wirkung und verliert daher mit der Deprecation des ES5-Targets seinen Zweck
--moduleResolution node (node10) deprecated
- Bildete den Modulauflösungsalgorithmus von Node.js 10 ab und entspricht nicht mehr dem Verhalten aktueller Node.js-Versionen
- Empfohlen wird die Migration zu
nodenext(direktes Targeting von Node.js) oderbundler(für Bundler/Bun)
AMD-, UMD- und SystemJS-Modulwerte deprecated
--module amd,--module umd,--module systemjsund--module nonewerden alle nicht mehr unterstützt- Da ESM in Browsern und Node.js allgemein unterstützt wird, ist ein Wechsel zu Bundlern oder ESM-Targets erforderlich
--baseUrl deprecated
- Wurde meist als Präfix für
pathsgenutzt, fungierte aber auch als Lookup-Root der Modulauflösung, was zu unbeabsichtigten Pfadauflösungen führen konnte - Die Migration erfolgt durch Entfernen von
baseUrlund direktes Hinzufügen des Präfixes in denpaths-Einträgen- Beispiel:
"@app/*": ["app/*"]→"@app/*": ["./src/app/*"]
- Beispiel:
--moduleResolution classic deprecated
- Der ursprüngliche Modulauflösungsalgorithmus von TypeScript; heute lassen sich praktisch alle realen Anwendungsfälle durch
nodenextoderbundlerersetzen
esModuleInterop false und allowSyntheticDefaultImports false deprecated
- Beide Optionen können nicht mehr auf
falsegesetzt werden, wodurch sicheres Interop-Verhalten immer aktiv ist - Erforderlich kann z. B. die Umstellung von
import * as express from "express"aufimport express from "express"sein
--alwaysStrict false deprecated
- Sämtlicher Code wird als JavaScript Strict Mode behandelt; Code, der
await,static,privateusw. als normale Bezeichner nutzt, muss umbenannt werden
outFile deprecated
- Diente zum Zusammenführen mehrerer Eingabedateien in eine Datei, wird aber durch externe Bundler wie Webpack, Rollup, esbuild oder Vite ersetzt
- Die Entscheidung dient dazu, TypeScript auf seine Kernrolle bei Type-Checking und Declaration Emit zu fokussieren
Legacy-module-Syntax (Namespace-Deklarationen) deprecated
- Die Syntax
module Foo { ... }ist hart deprecated; stattdessen mussnamespace Foo { ... }verwendet werden - Ambient-Module-Deklarationen der Form
declare module "some-module" { ... }bleiben weiter unterstützt - Ziel ist die Vermeidung von Konflikten mit dem ECMAScript-Vorschlag für
module-Blöcke
Import-Schlüsselwort asserts deprecated
import ... asserts { type: "json" }muss zuimport ... with { type: "json" }geändert werden- Hintergrund ist die Umstellung vom Proposal für Import Assertions auf das Proposal für Import Attributes (
with-Schlüsselwort)
Directive no-default-lib deprecated
/// <reference no-default-lib="true"/>wird nicht mehr unterstützt; empfohlen werden--noLiboder--libReplacement
Fehler bei Angabe von Kommandozeilen-Dateien, wenn tsconfig.json vorhanden ist
- Wird
tsc foo.tsausgeführt und im selben Verzeichnis liegt einetsconfig.json, tritt ein Fehler auf - Mit dem Flag
--ignoreConfigkann die Konfiguration explizit ignoriert werden
Vorbereitung auf TypeScript 7.0
- In 6.0 deprecated Optionen können mit
"ignoreDeprecations": "6.0"weiterhin ohne Fehler genutzt werden, werden in 7.0 aber vollständig entfernt - Mit dem ts5to6-Tool lassen sich Anpassungen wie bei
baseUrloderrootDirautomatisch vornehmen - TypeScript 7.0 soll innerhalb weniger Monate veröffentlicht werden und wird bereits breit in großen Codebasen innerhalb und außerhalb von Microsoft eingesetzt
- Feedback wird über die nightly Builds der Native Preview und die VS Code-Erweiterung empfohlen
3 Kommentare
Ich freue mich auf den Zeitpunkt, an dem vollständig auf den Go-basierten Compiler umgestellt wird!
Huch? Wird TypeScript später nativ auf Go-Basis umgestellt?
Nur der Compiler.