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.