TypeScript 7.0 wechselt den Compiler auf Go für native Geschwindigkeit
TypeScript 7.0 überträgt tsc auf Go mit parallelen Überprüfern, neuen Standardwerten für tsconfig, Unicode-Template-Literals, strengeren JS-Analysen sowie einer vorübergehenden Lücke in der programmatischen API.
Etwa vierzehn Jahre lang konnte der TypeScript-Compiler sich selbst kompilieren. tsc war TypeScript, das in JavaScript kompiliert wurde und unter Node lief. Als die Repositorien auf Millionen von Zeilen anwuchsen, wurde dieses selbsthostete Design zu einem Engpass.
TypeScript 7.0 ändert die Hostsprache. Der Compiler sowie der Sprachdienst wechselten von TypeScript zu Go. Microsoft bezeichnet diese Übertragung als Portierung statt Neuimplementierung: Die Struktur der Typüberprüfung entspricht noch der von 6.0, doch die Ausführung erfolgt in Form von natives Code mit paralleler Verarbeitung über gemeinsam genutzte Speicher. Veröffentlichte Vergleiche zeigen in der Regel eine Geschwindigkeitssteigerung von etwa 10× im Vergleich zu TypeScript 6.0.
Eine häufig zitierte Arbeitslast macht diesen Wechsel konkret sichtbar: Die Überprüfung des VS Code-Trees – mit etwa 1,5 Millionen Zeilen TypeScript – dauerte von rund 77,8 Sekunden auf etwa 7,5 Sekunden ab.
Für frühere Berichterstattungen wurde der Codename Project Corsa verwendet (wobei der herkömmliche JavaScript-Tree den Spitznamen Strada erhielt); diese Version ist die Umsetzung dieser Bemühungen.
Warum Go – und warum eine Portierung?
In der Öffentlichkeit wurde oft Rust als mögliche Alternative genannt. Go wurde gewählt, weil es mit der Struktur des bestehenden Compilers übereinstimmte: komplexe Graphen, Garbage Collection sowie zyklische Strukturen, die schwierig von Grund auf neu erstellt werden könnten. Diese Übereinstimmung machte eine Zeile-für-Zeile-Portierung möglich.
Die Struktur der Portierung ist wichtiger als die Sprachmarke. Durch Beibehaltung der Architektur blieben auch die Regeln erhalten. Projekte, die bereits unter 6.0 mit stableTypeOrdering aktiviert und ohne ignoreDeprecations Typüberprüfungen durchführen, sollten unter 7.0 dieselben Ergebnisse erhalten – ein schnelleres Engine-System, kein anderes Typsystem.
Zuerst fanden die Produktions-Testläufe statt. Über ein Jahr lang arbeitete der Port mit großen Strukturen an Orten wie Bloomberg, Figma, Google, Slack, Notion und Vercel, bevor dieses Meilenstein erreicht wurde.
Echter Parallelismus
Bislang begrenzte ein einzelner Node-Thread die Durchsatzleistung. Native Worker beseitigen diese Beschränkung. Version 7 verteilt die Aufgaben parse, check und emit sowie fügt Flags hinzu:
--checkerslegt die Anzahl der parallelen Typüberprüfungswerker fest--buildersparallelisiert die Kompilierung von Projektreferenzen sowie Stapelstrukturen in Monorepos zusammen mit--checkers--singleThreadedbündelt alles auf einen Kern zusammen, um bei der Fehlerbehebung sowie zur Messung von Basistiming-Daten zu helfen
Die Aufgaben parse/emit pro Datei skalen mit der Größe und Modularität des Repositoriums; kleine Ein-Datei-Anwendungen profitieren weniger davon.
Auch der Überwachungsmodus wurde neu gestaltet. Das Abfragen verbrauchte viel CPU bei großen node_modules-Strukturen; die Einbeziehung von Parcels Überwachungsfunktion in Go verringert diesen Aufwand und reagiert schneller auf Änderungen.
Konfigurationsänderungen, die Teams herausfordern
TypeScript 6.0 diente als Übergang: Neue Standardwerte und veraltete Funktionen wurden als Warnungen angezeigt. 7.0 macht sie zu schwerwiegenden Fehlern. Teams, die bereits TypeScript 6.0 durchlaufen haben, haben den größten Teil der Arbeit erledigt. Ein direkter Sprung von 5.x auf 7.0 erfordert Zeit zur Anpassung von tsconfig.json.
Bemerkenswerte Änderungen der Standardeinstellungen:
strictist standardmäßig aktiv, sofern nicht überschriebenmodulewird aufesnextgesetzt, währendtargetdie neueste stabile ECMAScript-Version voresnextauswähltnoUncheckedSideEffectImportsist standardmäßig aktivlibReplacementist standardmäßig deaktiviert
stableTypeOrdering bleibt aktiviert.rootDir beginnt bei ./.types startet als leere Liste.In den Dokumentationen werden rootDir und types als die ersten Probleme bezeichnet, auf die Teams stoßen – und als diejenigen mit den einfachsten Lösungen.
Falls tsconfig.json über einem src-Ordner liegt, geben Sie rootDir explizit an, damit die Ausgabe weiterhin vertraut aussieht:
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["./src"]
}
Weil types nicht mehr automatisch alles unter node_modules/@types importiert, listen Sie auf, was Sie benötigen:
{
"compilerOptions": {
"types": ["node", "jest"]
}
}
Optionen, die zuvor nur gewarnt haben, führen jetzt zu Fehlern (sie erledigen nichts Nützliches mehr):
- Löschen Sie
target: es5unddownlevelIteration.
moduleResolution-Werte (node, node10, classic) durch nodenext oder bundlermodule-Modi wie amd, umd, systemjs und none zugunsten von esnext oder preservebaseUrl und geben Sie die paths relativ zum Projektverzeichnis anesModuleInterop / allowSyntheticDefaultImports nicht auf false gesetzt werdenalwaysStrict als dauerhaft aktiviertFalls moduleResolution nach Jahren ohne Überprüfung immer noch auf den alten Wert node gesetzt ist, dient diese Datei als Migrationscheckliste.
Unicode in Template-Literal-Typen
Template-Literal-Typen beziehen sich nun auf Unicode-Codepunkte statt auf UTF-16-Codeeinheiten:
type HeadTail<S> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;
type Result = HeadTail<"😀abc">;
// In 7.0: ["😀", "abc"]
// Previously: ["\ud83d", "\ude00abc"]
Ältere Compiler konnten ein Surrogatpaar eines Emojis in zwei Teile aufteilen. Das spiegelte die Indizierung in JavaScript wider und entsprach selten der Absicht des Autors. Die Iteration folgt nun den Codepunkten, genauso wie for...of und [...str]. Hilfsfunktionen, die absichtlich UTF-16-Einheiten zählten, werden nicht mehr funktionieren; alle anderen erhalten das erwartete Verhalten.
Strengeere Analyse von JavaScript
.js-Prüfungen tolerierten früher mehr JSDoc- und Closure-Era-Ideale. Version 7 bringt diese Richtung stärker in Einklang mit den .ts-Regeln:
- Orte, die Typen benötigen, lehnen reine Werte ab – es wird
typeof someValuebevorzugt @enum/@classerhalten keine besondere Behandlung mehr; man muss eine echte Klasse deklarieren oder@typedefverwenden- Ein reines
?wird nicht als Typ akzeptiert – es wirdanybevorzugt
!-Assertionen werden nicht unterstützt – schreiben Sie explizit T.function(string): void-Formen werden durch (s: string) => void ersetzt.Das Defizit der programmatischen API
In Version 7.0 fehlt weiterhin eine stabile programmatische API. Bibliotheken, die den Compiler integrieren – wie ESLints TypeScript-Integration, ts-morph, selbst entwickelte Transformer sowie Editor-Hilfsmittel für Vue, Svelte, Astro, MDX oder Angular-Templates – können daher noch nicht vollständig umsteigen. Microsoft betrachtet dieses Defizit als vorübergehend und verspricht die Fertigstellung der API für Version 7.1 und spätere Releases.
Währenddessen kann man Version 7.0 verwenden, wenn keine Language-Server-Plugins erforderlich sind. Angular-Teams können beispielsweise tsc aus Version 7.0 nutzen, um schnelle CLI-Prüfungen im gesamten Projekt durchzuführen, während sie weiterhin Version 6.0 im Editor verwenden. Ein Kompatibilitätspaket namens @typescript/typescript6 stellt ein tsc6-Binärprogramm bereit und exportiert die 6.0-API erneut, sodass beide Versionen nebeneinander existieren können:
{
"devDependencies": {
"typescript": "npm:@typescript/typescript6@^6.0.0"
}
}
Sollten Sie upgraden?
Da bereits TypeScript 6.0 verfügbar ist, ist der Migrationsaufwand gering und die Vorteile groß: Man passt nur einige Einstellungen in tsconfig an und erhält schnellere CI-Prüfungen sowie ein schnelleres Starten des Editors. Bei älteren Versionen gibt es tatsächlich Kompatibilitätsprobleme, doch fast alle wurden bereits angekündigt.
Installieren Sie den Release Candidate noch heute:
npm install -D typescript@rc
Für Editor spricht heute ein VS Code-Add-on die LSP-Sprache, und die native Integration in VS Code erweitert sich stetig. Visual Studio erkennt Version 7.0 bereits im geöffneten Arbeitsbereich, ohne dass ein separater Installationsschritt erforderlich ist.
Die Betreuer geben an, dass die Funktionsveröffentlichungen wieder im gewohnten mehrmonatigen Rhythmus stattfinden, und es wird erwartet, dass Version 7.1 die Lücke in der Embedding-API schließt.
Letztes Ergebnis: die vertrauten TypeScript-Regeln, die als natives Code ausführt werden.