TypeScript never erklärt: Exhaustive Checks, assertNever, Conditional Types und warum never KI generierten Code absichert. Praxiswissen von NCA
Mehr erfahren
type Nutzer = {
id: string;
name: string;
email: string;
};
type NutzerUpdate = Partial<Nutzer>; // alle Felder optional
type NutzerVorschau = Pick<Nutzer, "id" | "name">;
type NeuerNutzer = Omit<Nutzer, "id">;
Ein Tag inhouse mit Benjamin Klein für Developer, Tester und Admins. Context Engineering, Harness, ADRs und zwei Hands on Blöcke mit KI Agenten in eurem Setup.
Vor allem KI generierter Code legt für jede Aufgabe gern einen neuen Typ an. Nach einigen Monaten gibt es dann mehrere Fassungen desselben Nutzers. Mit AI Slop Refactoring führen wir sie wieder zusammen und leiten Varianten sauber ab.
Im Team verankern wir das über die AI Coding Guidelines für TypeScript. Mehr zu unserer Arbeit steht unter Frontend Development, das gemeinsame Üben im KI Training für Entwicklerteams.
type Rolle = "admin" | "redaktion" | "gast";
const rechte: Record<Rolle, string[]> = {
admin: ["lesen", "schreiben", "löschen"],
redaktion: ["lesen", "schreiben"],
gast: ["lesen"],
};
async function ladeNutzer(id: string) {
return { id, name: "Ada", aktiv: true };
}
type Nutzer = Awaited<ReturnType<typeof ladeNutzer>>;
// { id: string; name: string; aktiv: boolean }
Wie sich solche Typen kombinieren lassen und was dahinter steckt, zeigt der never Eintrag am Beispiel von Exclude und NonNullable.
type Fehler = Omit<Nutzer, "emial">; // kein Compilerfehler, email bleibt drin
type Sicher = Pick<Nutzer, "id" | "name">; // Pick meldet falsche Schlüssel
const nutzer: Readonly<{ profil: { name: string } }> = {
profil: { name: "Ada" },
};
nutzer.profil = { name: "Linus" }; // Fehler
nutzer.profil.name = "Linus"; // erlaubt
TypeScript provides several utility types to facilitate common type transformations.
TypeScript never erklärt: Exhaustive Checks, assertNever, Conditional Types und warum never KI generierten Code absichert. Praxiswissen von NCA
Mehr erfahrenEine kurze Regel in der AGENTS.md hilft: Vor einem neuen Typ prüft der Agent, ob er sich aus einem vorhandenen ableiten lässt. Doppelte Dateien und ungenutzte Typen findet danach Fallow. In den Quality Gates für KI Code läuft das gemeinsam mit dem Type Check.
Technisch bauen Utility Types auf Generics auf. Typen aus Konfigurationsobjekten liefert satisfies, Typen aus Schemas liefert Zod. Der TypeScript Eintrag gibt den Überblick zur Sprache.
Optimieren Sie Ihre Webseite mit Astro JS und nutzen Sie die Vorteile einer schnellen, sicheren und barrierefreien Webseite. Erfüllen Sie die gesetzlichen Anforderungen und verbessern Sie die Benutzererfahrung Ihrer Webseite. Mit Astro JS können Sie die Ladezeit reduzieren, die Sicherheit maximieren und die SEO-Optimierung verbessern. Kontaktieren Sie uns, um mehr zu erfahren und um Ihre Webseite auf ein neues Level zu heben.
Eingebaute generische Typen, die aus einem vorhandenen Typ einen neuen erzeugen. Bekannte Beispiele sind Partial, Pick, Omit und Record. Du musst nichts importieren oder installieren. Sie existieren nur beim Kompilieren und erzeugen kein JavaScript.
Pick passt, wenn du wenige Felder aus einem großen Typ brauchst. Omit passt, wenn fast alle Felder bleiben sollen. Pick prüft dabei die Schlüssel und meldet Tippfehler, Omit nicht. Im Zweifel ist Pick deshalb die sicherere Wahl.
Record ist nur ein Typ für ein normales Objekt und verschwindet beim Kompilieren. Map ist eine echte JavaScript Struktur zur Laufzeit. Für feste Schlüssel aus einer Union passt Record. Für häufig wechselnde Einträge oder Schlüssel, die keine Texte sind, passt Map.
Nein. Readonly wirkt nur beim Kompilieren und nur auf der ersten Ebene. Verschachtelte Objekte bleiben änderbar, und zur Laufzeit gibt es keinen Schutz. Dafür brauchst du Object.freeze, das seinerseits ebenfalls nur die erste Ebene einfriert.
Ja, wenn der Agent dazu angehalten wird. Ohne Regel legt er für neue Aufgaben schnell eigene Typen an. Eine Vorgabe in der Regeldatei und ein Review, das auf Ableitungen achtet, halten die Zahl der Definitionen klein und das Datenmodell an einer Stelle.
Ja, sie lassen sich ineinander schachteln, etwa Partial und Pick für änderbare Felder oder Awaited und ReturnType für Ergebnisse asynchroner Funktionen. Bei mehr als zwei oder drei Ebenen wird es schwer lesbar. Dann hilft ein benannter Zwischentyp.
Der zweite Parameter von Omit ist bewusst nicht auf die Schlüssel des Typs beschränkt. Ein Tippfehler entfernt also einfach nichts. Wenn dich das stört, nimm Pick oder schreibe einen eigenen strengeren Typ für dein Projekt.
Ein eingebautes DeepReadonly gibt es nicht. Für feste Werte reicht oft as const, das auch verschachtelte Strukturen schreibgeschützt typisiert. Alternativ schreibst du einen eigenen rekursiven Typ oder nutzt eine erprobte Bibliothek. Das ist für die meisten Projekte selten nötig.
Ableiten, solange die Typen fachlich zusammengehören. Ein Update hängt am Nutzer und soll mitwachsen. Haben zwei Typen nur zufällig dieselben Felder, schreibst du sie besser getrennt. Sonst koppelst du Dinge, die sich später unabhängig ändern müssen.
Ja, mit Generics, Mapped Types und Conditional Types. Die eingebauten sind genauso aufgebaut. Für Anwendungscode reichen sie meist aus. Eigene lohnen sich, wenn ein Muster im Projekt oft vorkommt und der Name den Code wirklich lesbarer macht.