TypeScript 6 und 7: Intelligentere Inferenz, anschließend eine Umschreibung in Go
Erfahren Sie, wie TypeScript 6 Lücken bei der Schlüsselableitung behoben und Standardwerte modernisiert hat, wodurch der Weg für die vollständige Neuschreibung des Compilers in TypeScript 7 in Go bereitet wurde.
TypeScript hat sich kürzlich auf zwei verschiedenen Ebenen weiterentwickelt, und zusammen erzählen sie eine Geschichte: Die Sprache wird sowohl intelligenter als auch schneller. TypeScript 6, die als letzte Version im traditionellen, auf JavaScript basierenden Compiler vor dem großen architektonischen Wandel veröffentlicht wurde, konzentrierte sich darauf, seit langem bestehende Probleme bei der Inferenz zu beheben und die Standardeinstellungen zu modernisieren. TypeScript 7 ging dann den radikaleren Weg, den Compiler selbst in Go umzuschreiben, wobei das Ziel reine Geschwindigkeit statt neuer Syntax war. Wenn man beides zusammen betrachtet, wird deutlich, wie die Toolchain zu ihrem aktuellen Zustand gelangt ist – zunächst durch größere Genauigkeit und anschließend durch eine dramatische Beschleunigung.
Intelligenterere Inferenz in TypeScript 6
Jeder, der bereits eine Methode in Kurzform geschrieben hat und anschließend beobachtet hat, wie der Parameter stillschweigend in any umgewandelt wurde, weiß, wie frustrierend die alten Inferenzregeln von TypeScript sein können. TypeScript 6 behebt dieses Problem zusammen mit einigen weiteren Inferenzlücken, die Entwickler seit Jahren dazu gebracht haben, nach Lösungen zu suchen.
Zuvor wurde jede Funktion, die intern auf this verweist, als „kontextsensitiv“ betrachtet, was bedeutete, dass der Compiler die Inferenz des Parametertyps für sie völlig übersprang – selbst in Fällen, in denen this im Funktionskörper tatsächlich nie verwendet wurde:
// Old behavior: 'user' silently became 'any'
const handlers = {
onSave(user) {
console.log(user.name); // no autocomplete, no error
},
};
Mit TypeScript 6 betrachtet der Compiler eine Funktion nur dann als kontextsensitiv, wenn this tatsächlich darin verwendet wird. Andernfalls greift die normale Inferenz wieder und der Parameter erhält seinen erwarteten Typ, anstatt auf any zurückzugreifen:
// TypeScript 6: 'user' is correctly inferred from context
const handlers: Handlers = {
onSave(user) {
console.log(user.name); // fully typed
},
};
Es scheint sich um eine kleine technische Anpassung zu handeln, doch sie hat einen erheblichen Einfluss auf die tägliche Entwicklung – insbesondere in Codebasen von React und Next.js, wo Objektmethoden und Ereignishandler überall vorkommen.
TypeScript 6 bringt außerdem erstklassige Unterstützung für using-Deklarationen mit, die eine formale Ressourcenverwaltung ermöglichen. Anstatt die Aufräumlogik manuell in einen try/finally-Block zu packen, kann der Compiler die Freigabe automatisch übernehmen, sobald ein Wert außerhalb seines Gültigkeitsbereichs liegt:
function readConfig() {
using file = openFile("./config.json"); // auto-disposed at scope end
return JSON.parse(file.read());
}
Auch die Importe von Unterpfaden werden übersichtlicher. Das Präfix #/ funktioniert nun über das imports-Feld, wodurch man langen Ketten von relativen ../../../-Pfaden ausweichen kann:
{
"imports": {
"#/*": "./src/*"
}
}
import { formatCurrency } from "#/utils/currency";
// instead of: import { formatCurrency } from "../../../utils/currency";
Mehrere Standardwerte haben sich ebenfalls geändert. Die Option target verwendet nun standardmäßig ES2023 anstelle der veralteten ES3-Referenz, module standardmäßig ESNext und moduleResolution standardmäßig bundler. Auch die Option types standardmäßig auf ein leeres Array – dadurch scannt und lädt TypeScript nicht automatisch alle @types-Pakete, die es finden kann. Laut Microsoft führt allein diese letzte Änderung zu Verbesserungen bei der Kompilierzeit von 20 bis 50 Prozent, wodurch es sich lohnt, Ihre tsconfig.json-Datei zu überprüfen – selbst wenn Sie kein Interesse daran haben, neue Sprachfunktionen zu übernehmen.
Insgesamt lauten die Empfehlungen für TypeScript 6 wie folgt: Prüfen Sie alle methodenreichen Objekte in Ihrer Codebasis, da sie möglicherweise kostenlos automatische Verbesserungen der Typsicherheit erhalten; verwenden Sie using, wo immer Sie mit Dateien, Verbindungen oder Timern umgehen, die bereinigt werden müssen; übernehmen Sie nicht einfach stumm die neuen Compilerstandarde – legen Sie diese explizit in tsconfig.json fest, damit Ihre Absicht klar ist; und rechnen Sie damit, dass die von Frameworks und Bibliotheken wie React, Redux sowie Tailwind Tooling bereitgestellten Typdefinitionen in den kommenden Wochen diesen Änderungen folgen werden. TypeScript 6 ist keine vorübergehende Version – es verringert deutlich die Anzahl der überraschenden Schlussfolgerungen, auf die man im Alltag stößt, was bereits ein guter Grund für einen Upgrade ist.
Die grundlegende Neugestaltung in TypeScript 7
Während TypeScript 6 die Art und Weise, wie der Compiler mit Typen umgeht, verbesserte, konzentriert sich TypeScript 7 auf etwas Grundlegenderes: die Geschwindigkeit der gesamten Toolchain. Microsoft hat den Compiler, den Sprachdienst sowie die zugehörigen Werkzeuge vollständig in Go umgeschrieben und damit die jahrelang genutzte selbsthostete JavaScript-Implementierung ersetzt. Es handelt sich dabei nicht um einen kleinen Versionsaufpreis – es wird als der größte Leistungsunterschied in der Geschichte der Sprache beschrieben.
Jeder, der schon einmal auf den Ladeindikator eines Editors gestarrt hat, während man auf das Auftauchen eines Typfehlers wartete, wird den genauen Schmerzpunkt erkennen, den diese Überarbeitung anspricht.
Da das Team die ursprüngliche Compilerlogik übernommen hat anstelle der Typüberprüfungsregeln von Grund auf neu zu entwickeln, blieb die Kompatibilität mit bestehendem Code während des Übergangs größtenteils unverändert.
Die von Microsoft selbst veröffentlichten Benchmarks geben einen Eindruck vom Umfang der Verbesserungen. In der etwa 1,5 Millionen Zeilen umfassenden VS Code-Codebasis dauert ein vollständiger Build, der früher etwa 125 Sekunden in Anspruch nahm, nun nur noch rund 10 Sekunden. Die Zeit, bis der erste Typfehler im Editor sichtbar wird, sank von etwa 17 Sekunden auf unter 1,5 Sekunden. Der Speicherverbrauch verringerte sich um rund 18 Prozent, und Abstürze des Sprachservers nahmen um mehr als 60 Prozent ab. Es handelt sich dabei auch nicht ausschließlich um künstlich erzeugte Zahlen – Unternehmen wie Slack, Figma, Google, Notion und Vercel testeten den neuen Compiler bereits vor der Veröffentlichung in echten Produktionsprojekten und berichteten, dass die Vorteile auch außerhalb kontrollierter Benchmarks bestehen blieben.
Für Teams, die mit React und Next.js arbeiten, bedeutet dies konkrete Vorteile im Alltag. In einem großen Monorepo konnte das Warten darauf, dass tsc eine Typunterschiede erkennt, zuvor mehrere Sekunden in Anspruch nehmen; dieser Aufwand verringert sich unter dem auf Go basierenden Compiler erheblich:
// Before: waiting on tsc to catch this in a large monorepo could take seconds
interface UserCardProps {
name: string;
avatarUrl?: string;
onSelect: (userId: string) => void;
}
function UserCard({ name, avatarUrl, onSelect }: UserCardProps) {
// With TS7's native checker, this feedback loop is nearly instant
return (
<button onClick={() => onSelect(name)} className="rounded-lg p-2 hover:bg-slate-100">
{avatarUrl && <img src={avatarUrl} alt={name} className="h-8 w-8 rounded-full" />}
<span>{name}</span>
</button>
);
}
Große Next.js-Anwendungen mit Hunderten von Komponenten betrachten die Typüberprüfung nicht mehr als Engpass in den CI-Prozessen wie früher. Projekte, die mit umfangreichen Generiktypen erstellt wurden – beispielsweise solche, die Tailwind und Redux kombinieren – weisen deutlich schnellere inkrementelle Builds auf. Auch die Autocomplete-Funktion in großen Monorepos reagiert viel schneller.
Vor dem Upgrade gibt es einige Bedenken, die erwähnt werden sollten. Der strenge Modus ist nun Standard, wodurch zuvor locker strukturierte Codebasen neue Fehler aufweisen können. Herkömmliche Kompilierziele wie es5 sowie ältere Einstellungen zur Modulauflösung gelten nicht mehr nur als Warnungen – sie werden als schwerwiegende Fehler behandelt. Da die programmatische API in dieser Version nur teilweise stabil ist, sollten alle Frameworks oder Tools, die direkt von ihr abhängen, mit dem Upgrade bis zur Veröffentlichung von TypeScript 7.1 warten.
Alles dies beinhaltet weder neue Syntax noch grundlegend andersartige Grammatik – TypeScript 7 existiert hauptsächlich, um die seit einem Jahrzehnt bestehenden Beschwerden bezüglich der Compilerleistung zu beheben. Wenn Ihr Team eine große React- oder Next.js-Codebasis betreibt, ist dies die Version, die tsc endlich weniger wie etwas erscheinen lässt, gegen das man ankämpfen muss. Wie bei jedem großen Infrastrukturwandel lohnt es sich, zunächst auf einer Nebenbranche auszuprobieren; Ihr CI-Pipeline wird Ihnen für diese Vorsicht danken.
Verwandte Artikel
- TypeScript 7’s Go-Überarbeitung: Was das für die Typsicherheit in React bedeutet – Erfahren Sie, wie der auf Go basierende Compiler von TypeScript 7 die Kompilierung beschleunigt und die generische Inferenz verbessert, wodurch versteckte
any-Typen in React-Hooks und JSX beseitigt werden.