TypeScript satisfies erklärt: Objekte gegen einen Typ prüfen ohne Literaltypen zu verlieren, Unterschied zu as und Annotation, Praxisbeispiele von NCA
Mehr erfahren
function erstes<T>(liste: T[]): T | undefined {
return liste[0];
}
const name = erstes(["Ada", "Linus"]); // string | undefined
const zahl = erstes([1, 2, 3]); // number | undefined
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.
Generics schreiben wir täglich im typisierten Frontend Stack aus Astro, React und Vue, etwa für API Clients und wiederverwendbare Komponenten. Im Review schauen wir dabei auf eine Frage: Hilft der Typparameter dem Aufrufer, oder macht er nur die Signatur länger?
In deinem Projekt räumen wir überladene Typen auf und ersetzen any durch geprüfte Typen. Mit AI Slop Refactoring bringen wir KI generierten Code in Form, und die AI Coding Guidelines für TypeScript legen fest, was ein Agent darf. Die Abrechnung läuft transparent nach Minuten.
function erstesAny(liste: any[]): any {
return liste[0];
}
const wert = erstesAny(["Ada"]);
wert.gibtEsNicht(); // kompiliert, kracht zur Laufzeit
const name = erstes(["Ada"]);
name?.gibtEsNicht(); // Fehler beim Kompilieren
function laenge<T extends { length: number }>(wert: T): number {
return wert.length;
}
laenge("Hallo"); // ok
laenge([1, 2]); // ok
laenge(42); // Fehler: number hat kein length
function lese<T, K extends keyof T>(objekt: T, schluessel: K): T[K] {
return objekt[schluessel];
}
const nutzer = { name: "Ada", alter: 36 };
lese(nutzer, "alter"); // number
lese(nutzer, "email"); // Fehler: Schlüssel gibt es nicht
interface Antwort<T = unknown> {
daten: T;
status: number;
}
type Nutzer = { id: string; name: string };
async function lade<T>(
url: string,
pruefe: (wert: unknown) => T
): Promise<Antwort<T>> {
const antwort = await fetch(url);
const json: unknown = await antwort.json();
return { daten: pruefe(json), status: antwort.status };
}
Wichtig ist der Parameter pruefe. Ein fetch<Nutzer>() ohne Prüfung wäre nur eine Behauptung, weil Generics zur Laufzeit nicht existieren. An der Systemgrenze validiert deshalb ein Schema, zum Beispiel mit Zod.
being able to create a component that can work over a variety of types
TypeScript satisfies erklärt: Objekte gegen einen Typ prüfen ohne Literaltypen zu verlieren, Unterschied zu as und Annotation, Praxisbeispiele von NCA
Mehr erfahrenKI Agents neigen zu zwei Extremen: any an jeder schwierigen Stelle oder Typen über mehrere Zeilen, die niemand mehr prüft. Beides suchen wir im Codebase Audit für KI generierten Code. Die Regeln dagegen landen in der AGENTS.md und in den Quality Gates für KI Code.
Oft reicht statt eines Generics ein Union Type, und die fertigen Hilfstypen stehen bei den Utility Types. Einen Überblick zur Sprache gibt der TypeScript Eintrag. Wie der Compiler vergessene Fälle findet, zeigt der never Type. Teams üben das gemeinsam im KI Training für Entwicklerteams.
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.
Generics sind Typen mit Parametern. Eine Funktion oder ein Interface bekommt damit einen Typ als Eingabe und reicht ihn weiter. Der Code bleibt wiederverwendbar, und der Compiler kennt trotzdem den genauen Typ. Zur Laufzeit existieren Generics nicht, sie werden beim Kompilieren entfernt.
Wenn ein Typ von einem anderen abhängt, meist der Rückgabetyp vom Argument. Typische Fälle sind API Clients, Listenfunktionen und Formularfelder. Taucht der Typparameter nur einmal in der Signatur auf, verbindet er nichts. Dann reicht fast immer ein konkreter Typ oder unknown.
extends legt fest, was ein Typparameter mindestens können muss. T extends { length: number } erlaubt alles mit einer length Eigenschaft, etwa Strings und Arrays. Innerhalb der Funktion darfst du length dann lesen. Ein Aufruf mit einer Zahl scheitert schon beim Kompilieren.
Beide akzeptieren viele Typen, aber nur Generics merken sich den Typ. Bei any ist die Prüfung abgeschaltet, der Rückgabewert ist ebenfalls any. Bei einem Generic kommt derselbe Typ heraus, der hineingegeben wurde. Tippfehler bleiben dadurch sichtbar.
Sie helfen, wenn sie sparsam eingesetzt werden. Der Compiler meldet dem Agent falsche Felder und Rückgabewerte sofort. Zu verschachtelte Typen erzeugen dagegen lange Fehlermeldungen, an denen Mensch und Agent hängen bleiben. Eine Regel in der AGENTS.md begrenzt das.
Nein, meist leitet der Compiler ihn aus den Argumenten ab. Du schreibst dann nur erstes([1, 2]) statt erstes<number>([1, 2]). Explizit angeben musst du ihn, wenn es nichts zum Ableiten gibt, zum Beispiel bei einem leeren Array oder einem reinen Rückgabetyp.
Das ist nur eine Konvention, T steht für Type. Üblich sind auch K für Key und V für Value. Der Compiler akzeptiert jeden Namen. Bei mehreren Parametern lesen sich sprechende Namen wie TNutzer oder TAntwort im Review oft besser.
Nein. Generics werden beim Kompilieren entfernt, ein fetch<Nutzer>() prüft also gar nichts. Der Typ ist in dem Fall nur eine Behauptung. Daten aus APIs und Formularen validierst du an der Systemgrenze mit einem Schema oder einer eigenen Prüfung.
Mit interface Antwort<T = unknown> greift unknown, wenn beim Einsatz kein Typ angegeben wird. Das spart Schreibarbeit im häufigsten Fall. Hat der Parameter ein extends, muss der Standardwert dazu passen. Pflichtparameter dürfen außerdem nicht hinter optionalen stehen.
Du kannst die Signatur nicht mehr vorlesen, die Fehlermeldung füllt den halben Bildschirm oder niemand im Team traut sich an den Typ. Dann hilft es meist, die Funktion aufzuteilen. Für Bibliotheken ist mehr Aufwand vertretbar als für Anwendungscode.