Zum Danebenlegen beim Konfigurieren, Migrieren und Prüfen: welcher Schalter wofür, in welcher Reihenfolge der Wechsel läuft, wonach ein Review generierten Codes zuerst sucht. Die Typseite — Grundtypen, Unions, Generics, Validierung — steht auf dem Blatt TypeScript 7 Typsystem.
Maßgeblich sind die TypeScript-Dokumentation und die Release Notes zu 6.0 und 7.0; dieses Blatt ist eine Auswahl. Stand der Werkzeuglage: 08/2026 — der Punkt, der hier am schnellsten veraltet, ist die fehlende Compiler-API.
Drei Versionen, drei Aufgaben
| Version | Rolle | Wesentliche Änderung |
|---|---|---|
| 5.x | letzter Stand der alten Welt | Defaults noch nachsichtig, Altoptionen vorhanden |
| 6.0 | Übergang und Aufräumen | strict, esnext, es2025, types leer, baseUrl veraltet |
| 7.0 | neuer Motor | nativer Compiler, entfernte Optionen, keine API |
6.0 meldet als Warnung, was 7.0 als Fehler abweist — die Deprecation-Liste aus 6.0 ist damit die Arbeitsliste für 7.0. Der Sprung von 5.x direkt auf 7.0 bündelt zwei Umstellungen zu einer.
Modul: TypeScript 7 im JavaScript-Ökosystem
Was der native Compiler gemessen bringt
| Projekt | mit 6 | mit 7 | Faktor |
|---|---|---|---|
| VS Code | 125,7 s | 10,6 s | 11,9 |
| Sentry | 139,8 s | 15,7 s | 8,9 |
| Playwright | 12,8 s | 1,47 s | 8,7 |
| Prisma Console (Monorepo) | rund 74 s | rund 24 s | rund 3 |
Zahlen des TypeScript-Teams aus der Ankündigung vom 08.07.2026, Prisma nach
eigener Angabe. Das sind Messungen an fremden Projekten, keine Zusage —
Prisma nennt den Grund für den kleineren Faktor selbst: Nur ein Teil der
CI-Zeit steckte je in tsc.
Neben der Buildzeit gemessen: 18 bis 26 Prozent weniger Speicher, über 80 Prozent weniger fehlgeschlagene Language-Server-Kommandos, über 60 Prozent weniger Abstürze, Öffnen einer Datei mit Fehler von 17,5 s auf unter 1,3 s. Der vollständige Build läuft selten, der Language Server dauernd.
Modul: TypeScript 7 im JavaScript-Ökosystem · Performance Engineering
tsc: drei Aufgaben, ein Werkzeug
| Aufgabe | Aufruf | Wer sie im Alltag übernimmt |
|---|---|---|
| Typen prüfen | tsc --noEmit | fast immer tsc selbst |
| JavaScript erzeugen | tsc | oft ein Bundler statt tsc |
| Deklarationen erzeugen | tsc --declaration | tsc, für veröffentlichte Pakete |
"scripts": {
"typecheck": "tsc --noEmit",
"build": "tsc",
"test": "vitest run",
"ci": "npm run typecheck && npm test && npm run build"
}
typecheck als eigenes Skript ist die Voraussetzung dafür, dass Pipeline und
Coding Agent die Prüfung einzeln aufrufen können.
Modul: TypeScript 7 im JavaScript-Ökosystem · ESM, Module und moderne Toolchains
Modulauflösung: was gilt, was entfiel
| Option | Gültig | Entfernt |
|---|---|---|
| module | esnext, nodenext, preserve, commonjs | amd, umd, systemjs, none |
| moduleResolution | nodenext, bundler | node, node10, classic |
| Ausgabe bündeln | Sache eines Bundlers | outFile |
Die Wahl folgt einer einzigen Frage: Wer führt den Code am Ende aus?
| Ziel | module | moduleResolution |
|---|---|---|
| Direkt in Node ausführen | nodenext | nodenext |
| Durch einen Bundler | preserve | bundler |
| Bibliothek veröffentlichen | nodenext | nodenext |
| Altbestand mit CommonJS | commonjs | bundler oder nodenext |
Seit 6.0 neu erlaubt: moduleResolution: bundler zusammen mit
module: commonjs. Falsch wird es erst, wenn dasselbe Projekt beide Annahmen
zugleich trifft.
Modul: ESM, Module und moderne Toolchains
ESM gegen CommonJS, type-only Imports
| Merkmal | CommonJS | ECMAScript Modules |
|---|---|---|
| Auflösung | zur Laufzeit, synchron | statisch, vor der Ausführung |
| Syntax | require, module.exports | import, export |
| Dateiendung im Import | optional | erforderlich, je nach Auflösung |
| Top-Level await | nein | ja |
import type { Auftrag } from "./auftrag.js"; // verschwindet zuverlässig
import { lade } from "./auftrag.js";
verbatimModuleSyntax macht die Trennung verbindlich: Was im Quelltext steht,
steht auch im Ergebnis. Ein Modul, das nur Typen liefert, wird dann zur Laufzeit
nicht geladen — und Nebenwirkungen beim Import werden weder zufällig ausgelöst
noch verschluckt.
Modul: ESM, Module und moderne Toolchains
package.json als Modulvertrag
{
"type": "module",
"exports": { ".": "./dist/index.js" },
"imports": { "#domaene/*": "./dist/domaene/*" }
}
Subpath Imports (#domaene/auftrag.js) löst Node selbst auf — sie gelten also
auch zur Laufzeit, anders als paths ohne Bundler oder Loader. Fehlt exports,
ist der gesamte Dateibaum öffentlich.
Anwendung ist nicht Bibliothek:
| Frage | Anwendung | Bibliothek |
|---|---|---|
| Deklarationen | optional | zwingend |
| Öffentliche Signaturen | intern änderbar | Zusage über Jahre |
| Konfiguration | pragmatisch | streng und explizit |
| Modulformat | eines genügt | oft beide Welten zu bedienen |
Modul: ESM, Module und moderne Toolchains
Migration: die Reihenfolge und ihr Grund
| Schritt | Warum |
|---|---|
| Auf 6.0 gehen | meldet als Warnung, was 7.0 als Fehler abweist |
| ignoreDeprecations entfernen | 7.0 kennt den Schalter nicht mehr |
| stableTypeOrdering einschalten | bildet die Typordnung von 7.0 vorab nach |
| Sauber übersetzen | erst dann gilt die Zusage überhaupt |
| Auf 7.0 wechseln | der kleinste Schritt der ganzen Migration |
stableTypeOrdering kostet bis zu 25 Prozent Prüfzeit und wird nach dem
Wechsel wieder entfernt. Der Compilerwechsel selbst ändert am Code nichts — die
Arbeit steckt in den geänderten Voreinstellungen aus 6.0.
Modul: Migration auf TypeScript 7
Geänderte Voreinstellungen ab 6.0
| Option | bis 5.x | ab 6.0 |
|---|---|---|
| strict | false | true |
| module | commonjs | esnext |
| target | es2015 | es2025 |
| types | alle @types | leer, explizit zu setzen |
| rootDir | aus den Quellen abgeleitet | das tsconfig-Verzeichnis |
| esModuleInterop | false | true, nicht abschaltbar |
| noUncheckedSideEffectImports | false | true |
Praktische Folge: types und rootDir gehören jetzt in jede tsconfig, die
Node-Globals braucht oder eine vorhersehbare Ausgabestruktur will. Was Default
ist, gehört dagegen nicht in die Datei — sie wird sonst unlesbar.
{
"compilerOptions": {
"module": "nodenext",
"types": ["node"],
"rootDir": "./src",
"outDir": "./dist",
"declaration": true
},
"include": ["src"]
}
Modul: Migration auf TypeScript 7 · TypeScript 7 im JavaScript-Ökosystem
Was verschwindet, was an die Stelle tritt
| Entfallen | Ersatz | Anmerkung |
|---|---|---|
| target es5 | mindestens es2015 | alte Laufzeit: Schritt danach |
| downlevelIteration | entfällt mit es5 | funktionierte nur dort |
| outFile | ein Bundler | Bündeln war nie Compilerarbeit |
| amd, umd, systemjs, none | esnext, nodenext, preserve | Altformate |
| assert bei Importen | with | Import Attributes |
| baseUrl | Subpath Imports, rootDir | entfällt in 7.0 |
Für die mechanische Arbeit an baseUrl und rootDir gibt es ein Werkzeug —
in der Quelle als experimentell gekennzeichnet, und die Architekturfrage, ob
paths überhaupt bleiben sollen, liefert es nicht mit:
npx @andrewbranch/ts5to6 --fixBaseUrl .
npx @andrewbranch/ts5to6 --fixRootDir .
Modul: Migration auf TypeScript 7
Zwei benannte Verhaltensunterschiede
| Abweichung | Sichtbar in | Risiko |
|---|---|---|
| Union-Ordnung | Fehlermeldungen, Tooltips | Snapshot-Tests brechen |
| Union-Ordnung | generierten Deklarationen | Diffs ohne fachlichen Grund |
| Union-Ordnung | seltenen Grenzfällen | Fehler erscheint oder verschwindet |
| Unicode in Template Literals | Typen, die Text zerlegen | stille Ergebnisänderung |
Gezielt danach suchen heißt: Snapshot-Tests über Fehlermeldungen zuerst laufen lassen, generierte Deklarationen vor und nach dem Wechsel vergleichen, beide Compiler dieselbe Codebasis prüfen lassen.
Modul: Migration auf TypeScript 7
Die fehlende Compiler-API und der Parallelbetrieb
TypeScript 7.0 bringt keine Compiler-API mit; sie ist für 7.1 vorgesehen, aber nicht datiert. Betroffen ist jedes Werkzeug, das den Compiler als Bibliothek einbindet:
| Braucht das Werkzeug den Compiler als Bibliothek? | Betroffen | Beispielklasse |
|---|---|---|
| Ja, liest Syntaxbaum oder Typen | ja, wartet auf 7.1 | typbezogene Lint-Regeln |
| Ja, über eingebettete Sprachen | ja | Vue, Svelte, Astro, MDX |
| Nein, eigener Parser | nein | Formatierer, Bündler |
| Nein, ruft nur tsc auf | nein | Prüfskripte in der Pipeline |
Prüffrage: Steht typescript in den Abhängigkeiten des Werkzeugs? Dann
betroffen. Bis dahin der Parallelbetrieb — tsc prüft nativ, die Werkzeuge
importieren weiter die 6er-API:
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
--force oder --legacy-peer-deps bringen die API nicht hervor.
Modul: Architektur, Qualität und Tests · Migration auf TypeScript 7
Performance-Flags
tsc # Standard: vier Prüf-Worker
tsc --checkers 8 # mehr Worker, mehr Speicher
tsc --checkers 1 # einer, für Diagnose und Vergleich
tsc --build --builders 4 # Teilprojekte nebenläufig
tsc --build --builders 4 --checkers 2 # wirkt multiplikativ
| Umgebung | Was knapp ist | Sinnvolle Richtung |
|---|---|---|
| Entwicklerrechner | selten etwas | Standard belassen |
| Großer CI-Läufer | nichts | checkers erhöhen, messen |
| Kleiner CI-Container | Speicher | checkers senken, notfalls einfädig |
| Monorepo-Build | beides | builders und checkers zusammen denken |
Mehr Prozesse können langsamer sein: Jeder Worker hält eine eigene Sicht auf die
Typinformation im Speicher; reicht der nicht, lagert das System aus. Und der
Gewinn von --builders hängt an der Form des Abhängigkeitsgraphen, nicht an der
Zahl der Pakete — erst die Referenzen schneiden, dann die Flags drehen.
Modul: Performance Engineering
Quality Gates
| Tor | Beantwortet | Fällt aus, wenn |
|---|---|---|
| Typprüfung | Passt der Code zu sich selbst? | sie im Build-Schritt versteckt ist |
| Linting | Ist es zulässig und trotzdem unklug? | die Werkzeuglage sie blockiert |
| Tests | Rechnet es richtig? | niemand — sie bricht sichtbar |
| Build | Lässt es sich ausliefern? | niemand — er bricht sichtbar |
| Abhängigkeiten | Ist etwas Bekanntes verwundbar? | die Meldung zur Gewohnheit wird |
Ein rotes Tor blockiert — sonst ist es kein Tor, sondern ein Hinweis. Und derselbe Befehl muss lokal laufen wie in der Pipeline, sonst gilt er als Schikane.
Type-level und Runtime beantworten verschiedene Fragen:
| Frage | Type-level | Runtime |
|---|---|---|
| Ist die Verwendung möglich? | ja, prüft genau das | nein |
| Ist das Ergebnis richtig? | nein | ja, prüft genau das |
| Bricht bei Modellumbau | ja, beim Übersetzen | nur wenn es zufällig auffällt |
| Kostet | Übersetzungszeit | Laufzeit im Testlauf |
// @ts-expect-error — darf nicht übersetzen, cent fehlt
const kaputt: Auftrag = { nummer: nr };
expect(summe([a, b])).toBe(17800);
Modul: Architektur, Qualität und Tests
Coding Agents: Stufen und geeignete Aufgaben
| Stufe | Vorbereitung | Kontrolle |
|---|---|---|
| Code Completion | keine | beim Tippen, sofort sichtbar |
| Chat-Assistent | die Frage | Antwort lesen und bewerten |
| Repository-aware Agent | Kontext und Konventionen | Diff prüfen |
| Delegierte Aufgabe | Auftrag, Plan, Prüfkriterium | Nachweis statt Behauptung |
Zwei Fragen entscheiden über die Eignung einer Aufgabe — ist sie beschreibbar, und ist das Ergebnis maschinell prüfbar?
| Aufgabe | Beschreibbar? | Maschinell prüfbar? |
|---|---|---|
| Migration über viele Dateien | ja | ja, der Compiler prüft |
| Testabdeckung ergänzen | ja | ja, Abdeckung und Testlauf |
| Fehler mit Reproduktion beheben | ja | ja, der Test schlägt vorher fehl |
| Architekturentscheidung treffen | nein | nein |
| Fachliche Anforderung klären | nein | nein |
Ein Auftrag hat vier Teile: Ziel (was geändert wird), Kontext (welche Dateien, Beispiele, Fehler zählen), Randbedingungen (Standards, Architektur, Sicherheit) und Abschlusskriterium (was wahr sein muss). Fehlt das letzte, ist fertig, was fertig aussieht.
Modul: Von AI-assisted Coding zu Agentic Coding
Repository Instructions
| Mechanik | Was das bedeutet |
|---|---|
| Reihenfolge | global, dann von der Repository-Wurzel abwärts |
| Zusammenführung | aneinandergehängt, durch Leerzeilen getrennt |
| Vorrang | die näher am Arbeitsverzeichnis liegende gewinnt |
| Je Verzeichnis | höchstens eine Datei, Override-Fassung hat Vorrang |
| Obergrenze | zusammengeführt 32 KiB als Voreinstellung |
Was über der Obergrenze liegt, geht verloren — unsichtbar und ungemeldet.
| Hinein | Heraus |
|---|---|
| Befehle, die sich nicht erraten lassen | alles, was aus dem Code ablesbar ist |
| Stilregeln, die vom Üblichen abweichen | Sprachkonventionen, die ohnehin gelten |
| Testanweisungen und bevorzugte Testläufer | API-Dokumentation — besser verlinken |
| Branch- und PR-Regeln des Repositories | Information, die sich häufig ändert |
| Projektspezifische Architekturentscheidungen | lange Erklärungen und Tutorials |
| Eigenheiten der Entwicklungsumgebung | Datei-für-Datei-Beschreibung der Codebasis |
| Bekannte Fallstricke | Selbstverständliches wie „sauberen Code schreiben” |
Prüffrage je Zeile: Würde ihr Fehlen zu Fehlern führen? Wenn nein, streichen. Wird eine Regel trotz Nennung missachtet, ist die Datei meist zu lang.
Modul: Repository Instructions und Guardrails
Beratend oder verbindlich
| Ebene | Wirkung | Beispiel |
|---|---|---|
| Anweisungsdatei | beratend | keine neuen Abhängigkeiten ohne Rückfrage |
| Berechtigung, Sandbox | verbindlich, vorher | Schreib- und Netzzugriff begrenzen |
| Hook | verbindlich, deterministisch | Schreiben in ein Verzeichnis blockieren |
| Tor in der Pipeline | verbindlich, nachher | Prüfung, Lint, Test, Build |
Eine Bitte in der Anweisungsdatei ist keine Zugriffskontrolle. Die Datei bleibt trotzdem nötig — sie erklärt das Warum, das eine Sperre nicht mitliefert.
Modul: Repository Instructions und Guardrails
Review eines generierten Diffs
Konfiguration zuerst, dann der Code — eine entschärfte Konfiguration hebt die Aussagekraft aller übrigen Prüfungen auf:
git diff -- tsconfig.json eslint.config.*
git diff | grep -nE ": *any|as +[A-Z]|![.)]"
| Frage | Sucht nach |
|---|---|
| Wurde die Konfiguration entschärft? | tsconfig, Regelwerk |
| Sind any, Casts oder Assertions hinzugekommen? | stillen Konstruktionen |
| Gibt es eine Prüfung, wo Daten eintreffen? | fehlender Validierung |
| Bleibt ein unmöglicher Zustand darstellbar? | verflachten Zustandsmodellen |
| Ist die Vollständigkeitsprüfung noch da? | entfallener never-Prüfung |
| Hat sich eine öffentliche Signatur geändert? | gebrochenen Konsumenten |
| Kam eine Abhängigkeit hinzu? | unbesprochenen Entscheidungen |
| Würde ein Test irgendeine Fehlfunktion bemerken? | Tests ohne Aussage |
| Wurden Berechtigungen oder Hooks berührt? | verschobenen Grenzen |
Der Unterschied zwischen gelöst und verborgen an einem Beispiel — beide Fassungen übersetzen:
const summe = auftrag.cent! + gebuehr; // verborgen
if (auftrag.zustand !== "freigegeben") return; // gelöst
const summe = auftrag.cent + gebuehr;
Was im generierten Code regelmäßig fehlt:
| Fall | Typisch behandelt? | Woran es auffällt |
|---|---|---|
| Erfolgspfad | ja, zuverlässig | nichts zu tun |
| Leeres Ergebnis | oft nicht | kein Zweig für die leere Liste |
| Zeitüberschreitung | selten | kein Abbruch, kein Timeout |
| Verbotener Übergang | fast nie | kein Zweig, keine Prüfung |
| Gleichzeitiger Zugriff | fast nie | keine Sperre, kein Konflikt |
Und ein Test, der nichts prüft, bleibt grün:
expect(rabatt(10000)).toBe(10000 * 0.9); // baut die Implementierung nach
expect(rabatt(10000)).toBe(9000); // nennt das erwartete Ergebnis
Modul: Qualitätssicherung KI-generierten Codes
Generierte Typmodelle prüfen
| Muster | Wirkung | Erkannt durch |
|---|---|---|
| any an Systemgrenzen | Prüfung fällt still aus | Suche nach any im Diff |
| unnötige Type Assertions | Compiler wird übergangen | Suche nach as und ! |
| optional statt nullable | Bedeutung verschoben | Frage: darf es fehlen? |
| Typ ohne Laufzeitprüfung | Behauptung ohne Deckung | Frage nach der Grenze |
| Übermodellierung | niemand wartet es mehr | Fehlermeldung lesen |
| Konfiguration von vorgestern | veraltet oder entfernt | Abgleich mit 6.0 und 7.0 |
Der Vorschlag, der überall auftaucht — target: es5 und
moduleResolution: node sind seit 6.0 Fehler, baseUrl entfällt in 7.0,
strict ist Voreinstellung. Der Grund ist der Kalender: 6.0 kam im März 2026,
7.0 am 8. Juli 2026; Trainingsdaten davor kennen überwiegend die 5.x-Ära.
Aus fünf Beispielantworten lässt sich Optionalität nicht ableiten, nur beobachten — der Vorschlag ist ein Anfang, kein Ergebnis. Und: Ein Assistent schlägt für eine fachliche Regel meist nur den Typ vor; die Laufzeitprüfung fehlt und fällt nicht auf.
| Invariante | Ort | Warum dort |
|---|---|---|
| Freigabe erst nach Diagnose | Typ | Zustandsübergang |
| Betrag nur in bestimmten Zuständen | Typ | Feld existiert sonst gar nicht |
| Betrag nie negativ | Validierung | Zahlbereich, zur Laufzeit prüfbar |
| Ende nicht vor Beginn | Validierung | Beziehung zweier Werte |
| Kennung gehört einer Filiale | beides | Typ trennt, Prüfung bestätigt |
Modul: KI-gestützte Typmodellierung
Typische Fallen
ignoreDeprecationsauf 6.0 setzen und die Arbeit für erledigt halten.- Von 5.x direkt auf 7.0 springen — zwei Umstellungen in einer.
- Umstellen, obwohl Vue, Svelte, Astro, MDX oder Angular-Templates im Spiel sind. Sie brauchen die Compiler-API.
- Einen Migrationstermin zusagen, bevor die Werkzeuge geprüft sind — und einen Termin für 7.1 gibt es nicht.
- Defaults ausschreiben, bis die tsconfig unlesbar ist; oder
typesweglassen und sich über unbekannte Node-Globals wundern. pathsbehalten ohne Bundler oder Loader — der Compiler löst auf, die Laufzeit nicht.- Die Dateiendung im Import weglassen, weil es beim Übersetzen funktioniert.
- Die Typprüfung im Build-Schritt verstecken oder nur im Editor laufen lassen. Ein erfolgreicher Bundler-Lauf bedeutet keine geprüften Typen.
- Ein Tor abschalten, weil die Werkzeuglage klemmt, ohne es zu vermerken.
- Faktor 10 versprechen und Faktor 3 liefern — fremde Messungen sind keine Zusage für die eigene Codebasis.
--checkershochdrehen, ohne den Speicher des CI-Läufers zu kennen.- Der Zusammenfassung eines Agenten glauben, ohne den Diff geöffnet zu haben.
- Jeden Befund eines Prüfers abarbeiten — wer beauftragt ist, Lücken zu finden, findet welche. Das erzeugt Über-Engineering.
- Prüfen lassen von derselben Sitzung, die den Code geschrieben hat.
- Abdeckungsgrad als Qualitätsmaß nehmen — er misst Ausführung, nicht Prüfung.
- Sperren nur aufschreiben, ohne sie technisch zu verankern. Fremde Inhalte im Repository sind nicht vertrauenswürdiger als eine Netzantwort — belegt durch CVE-2025-53773 (Command Injection, CVSS 7,8 laut Hersteller): Die Anweisung steckte in Dateien des Arbeitsbereichs und änderte die Konfiguration so, dass Aktionen nicht mehr bestätigt wurden.
Dieses Thema als Schulung für Ihr Team
Dieser Beitrag erklärt das Thema. Damit Ihr Team es danach auch anwendet, gibt es Modern TypeScript 7 als Schulung — an Ihrem eigenen Code, mit den Fragen, die ein Text nicht beantwortet. Sie wählen die Module, wir bauen daraus ein Programm.
3 Tage·ab 900 EUR netto pro Tag (bis 3 Teilnehmende) ·Termin nach Vereinbarung