Upgrade einer React-Codebasis auf TypeScript 6.0: Was bricht zuerst?
Wie die strengeren Standardwerte von TypeScript 6.0, die Behebung der Methode-Inferrier-Probleme, die #/-Unterpfad-Importe sowie die Temporal-Typen eine React-Anwendung beeinflussen – zusammen mit einer sicheren Upgrade-Checkliste.
Quellen: TypeScript 6.0 for React Developers: What Actually Changed
Die meisten Compiler-Updates bleiben unbemerkt. TypeScript 6.0 ist anders: Es handelt sich um die letzte Version, die auf dem ursprünglichen JavaScript-Compiler basiert, und dient hauptsächlich dazu, Codebasen auf TypeScript 7 vorzubereiten, das auf Go beruht. Deshalb bringt es weniger neue Funktionen mit sich und stattdessen mehr Änderungen, die bestehende Probleme offenbaren. Diese Anleitung beschreibt, wie sich eine React-Codebasis tatsächlich verändern wird, und endet mit einer Checkliste für das Upgrade. Zur Rolle von 6.0 bei der Umstellung auf den nativen Compiler siehe TypeScript 6s Brückenfunktion auf dem Weg zu einem nativen TS 7-Compiler.
Strengeere Standardwerte zuerst
TypeScript 6.0 schaltet den strengen Modus standardmäßig ein, geht von ES-Modulen aus und setzt das Standardziel auf es2025. Projekte, die alle Optionen explizit festlegen, bleiben unberührt; Projekte, die von den alten, lockeren Standards abhängig waren, werden mit einer Welle neuer Fehler konfrontiert. In React-Code sind die üblichen Betroffenen ältere Komponenten: schwach typisierte Props, Handler mit impliziten any-Parametern, Refs, die null sein können, sowie useState() ohne Typargument. Dies sind keine Rückschritte, sondern seit langem bestehende Mehrdeutigkeiten, die nun berichtet werden.
Auch die Zielversionen es3 und es5 sind veraltet, wodurch die Mindestversion auf es2015 festgelegt wird. Für viele React-Anwendungen ändert sich dadurch wenig, da Babel, SWC oder esbuild die Syntax abbauen und tsc lediglich Typüberprüfungen durchführt – bestätigen Sie dies jedoch, bevor Sie Ihre Browserunterstützung neu überdenken. Führen Sie den Upgrade auf einer separaten Branch mit vollständiger Build- und Testumgebung durch; die Änderung der Compiler-Einstellungen an einem Freitagnachmittag ist ein zuverlässiger Weg, das Wochenende zu verlieren.
Konsistente Inferenz für Funktionen im Methodenstil
Eine weniger offensichtliche Verbesserung betrifft den Fall, in dem eine Funktion als „kontextsensitiv“ gilt – das bedeutet, ihre Parametertypen müssen aus dem Kontext stammen, bevor die Inferenz fortgesetzt werden kann. In 6.0 wird eine function-Expression oder Methodeabkürzung nur noch auf diese Weise behandelt, wenn tatsächlich this verwendet wird. Zuvor konnte die Wahl der Methodensyntax statt einer Pfeilfunktion die generische Inferenz verändern, selbst wenn this überhaupt nicht berührt wurde. Der untenstehende Hook mischt beide Stile:
// Before: inconsistent inference depending on syntax
const useCounter = (initial) => {
const [count, setCount] = useState(initial);
// this pattern used to infer differently than an arrow fn
const increment = function () {
setCount((c) => c + 1);
};
return { count, increment };
};
Zuvor konnte eine Callback-Funktion wie increment im Vergleich zu einer äquivalenten Pfeilfunktion anders infiziert werden, und in größeren Hooks konnte dieser Unterschied schwächere Typen an die Aufrufer weitergeben. Jetzt ändert die von Ihnen gewählte Syntax für Callbacks und zurückgegebene Hilfsfunktionen die resultierenden Typen nicht mehr, wodurch eine verwirrende Quelle für Fehler vom Typ „Warum wird dieser Callback nicht überprüft?“ beseitigt wird.
Sauberere Importe mit dem #/-Präfix
Die Subpfad-Importe von Node definieren private Aliase im Feld imports von package.json, und TypeScript 6.0 unterstützt dort das #/-Präfix, das den von Bundlern üblicherweise verwendeten Wurzel-Aliasen entspricht. Deklarieren Sie die Zuordnung einmal:
{
"imports": {
"#/*": "./src/*"
}
}
Dann importieren die Komponenten vom Projektwurzelverzeichnis anstelle davon, ../-Segmente zu zählen:
// No more relative path spaghetti in deeply nested components
import { useAuth } from "#/hooks/useAuth";
import { Button } from "#/components/ui/Button";
Weil der Alias in package.json und nicht nur in den paths von tsconfig.json gespeichert ist, lösen Node und TypeScript ihn identisch auf, ohne zusätzliche Plugins. Dies gilt nur in Auflösungsmodi, die package.json-Importe lesen, wie zum Beispiel nodenext oder bundler.
Temporäre Typen sind bereits integriert
TypeScript 6.0 enthält Deklarationen für die Temporal API, die die Endphase der TC39-Standardisierung erreicht hat. Teams, die Benutzeroberflächen für Terminplanung, Buchungen oder Dashboards entwickeln, können Temporal.PlainDate oder Temporal.ZonedDateTime ohne zusätzliches Paket verwenden, anstatt mit Date umzugehen. Die Typen bieten jedoch keine Laufzeitunterstützung – überprüfen Sie die native Unterstützung in Ihren Zielbrowsern und Node-Versionen und fügen Sie bei Bedarf einen Polyfill hinzu.
Sollten Sie jetzt upgraden?
Ja, bewusst. Das TypeScript-Team präsentiert 6.0 als stabile Aktualisierung, doch die dahinterliegenden Änderungen sind tatsächlich vorhanden:
- Audieren Sie
tsconfig.jsonund festlegen Sie jede Option, auf die Sie angewiesen sind. - Beseitigen Sie neue Fehler im strengen Modus in älteren Komponenten, anstatt sie mit
anyzu überspielen. - Stellen Sie fest, welches Tool eine Downleveling-Funktion bietet und welche Zielversion erforderlich ist.
noImplicitOverride zu aktivieren, damit überschriebene Member explizit mit override deklariert werden müssen.Zusammenfassung
TypeScript 6.0 wird nicht die Art und Weise ändern, wie Sie React programmieren, doch es macht die durch lockere Standardwerte verborgenen Probleme sichtbar. Diese jetzt, nach Ihrem eigenen Zeitplan, zu beseitigen, ist weitaus günstiger, als es später im Jahr zu tun, wenn außerdem auf Version 7 gewechselt wird – dadurch wird der spätere Wechsel hauptsächlich zu einer Leistungsfrage.