TypeScript Academy · Lektion

Eine Fluent-Query-DSL entwerfen

Erstellen Sie eine verkettbare Query-API, die sich selbst validiert.

Lektion 2 von 413 Schritte

Eine Fluent-Query-DSL entwerfen ist eine kostenlose TypeScript Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des TypeScript Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der TypeScript Academy-Kurs umfasst insgesamt 4 Lektionen.

Eine Fluent-Query-DSL entwerfen

Wir entwerfen eine verkettbare Query-DSL, bei der jeder Schritt über Rückgabetypen die zulässigen nächsten Schritte weiter einschränkt. Das Ergebnis liest sich wie SQL und weist ungültige Reihenfolgen bereits bei der Kompilierung zurück.

Die Zielgrammatik

Wir möchten: zuerst from, danach optional where (wiederholbar) und anschließend das abschließende select. Sie können select nicht vor from aufrufen und from nicht zweimal.

Zustands-Interfaces

Modellieren Sie jede Phase als ein Interface, das die nächste Phase zurückgibt.

interface Builder {
  from(table: string): FromStage;
}
interface FromStage {
  where(cond: string): FromStage; // repeatable
  select(...cols: string[]): Result;
}
interface Result { sql: string; }

Reihenfolge erzwingen

Da select nur auf FromStage vorhanden ist, führt der Aufruf auf dem initialen Builder zu einem Compile-Fehler. Die Reihenfolge wird ausschließlich dadurch erzwungen, welche Methoden die einzelnen Phasen bereitstellen.

declare const db: Builder;
db.from("users").select("id"); // ok
db.select("id");               // Error: select missing on Builder

Ausgewählte Spalten verfolgen

Fügen Sie ein Phantom-Generic hinzu, um sich zu merken, welche Spalten ausgewählt wurden, damit der Ergebnistyp präzise ist.

interface FromStage<T extends string = never> {
  where(c: string): FromStage<T>;
  select<C extends string>(...cols: C[]): Result<C>;
}
interface Result<C extends string> { columns: C[]; }

Mit jedem Aufruf verfeinern

Auch jeder where-Aufruf kann Einschränkungen im Typ ansammeln. Hier halten wir es einfach, aber das Muster lässt sich verallgemeinern, um gebundene Parameter zu verfolgen.

const q = db.from("users").where("age > 18").where("active = true");
// still FromStage; select remains available

Wiederholte from-Aufrufe verhindern

Da FromStage kein from bereitstellt, können Sie es nicht zweimal aufrufen. Die Grammatik verbietet dies strukturell, ohne dass eine Laufzeitprüfung erforderlich ist.

db.from("a").from("b"); // Error: from does not exist on FromStage

Ein abschließender Schritt

select gibt Result zurück. Dieser Typ stellt weder where noch from bereit und beendet damit die Kette. Es bleiben nur noch Operationen zum Lesen des Ergebnisses.

const r = db.from("users").select("id", "name");
r.columns; // ("id" | "name")[]
// r.where(...) -> Error: where not on Result

Typisierte Spalteneinschränkungen

Schränken Sie Spalten mit einem weiteren Generic auf ein bekanntes Tabellenschema ein, sodass unbekannte Spalten abgelehnt werden. Damit verbinden Sie diese DSL mit den früheren ORM-Konzepten.

interface Table<Cols extends string> {
  select<C extends Cols>(...cols: C[]): Result<C>;
}
// db.from gives Table<"id" | "name" | "age">

Optionale und erforderliche Schritte

Machen Sie einen Schritt erforderlich, indem Sie die nächste Methode erst danach bereitstellen. Erzwingen Sie beispielsweise mindestens ein where, indem Sie eine Phase zurückgeben, in der select erst nach dem Aufruf von where verfügbar ist. Dieselben verketteten Typen können außerdem den Ergebniszeilentyp der ausgeführten Abfrage ableiten und so die Grammatik zur Compilezeit mit den Daten zur Laufzeit verbinden.

Warum das wichtig ist

Eine auf diese Weise entworfene Fluent-DSL dokumentiert sich selbst und kann nicht falsch verwendet werden: Die Autovervollständigung zeigt nur gültige nächste Schritte, und unzulässige Sequenzen werden nie kompiliert. Das ist die Grundlage ergonomischer Builder-Bibliotheken.

Kurzer Test

Bestätigen Sie Ihr Verständnis des Entwurfs von Fluent-DSLs.

Zusammenfassung

Sie haben eine Fluent-Query-DSL als Zustandsmaschine auf Typebene entworfen: Jedes Phasen-Interface gibt die nächste Phase zurück und stellt nur gültige Methoden bereit. Phantom-Generics verfolgen ausgewählte Spalten, abschließende Phasen beenden die Kette, und Spalteneinschränkungen weisen unbekannte Namen zurück – alles wird durch Rückgabetypen erzwungen.

Kostenlos starten

Lerne TypeScript mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
101
Lektionen
352

Häufig gestellte Fragen

Ist die Lektion „Eine Fluent-Query-DSL entwerfen“ kostenlos?

Ja — der vollständige Text von „Eine Fluent-Query-DSL entwerfen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des TypeScript Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der TypeScript Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Eine Fluent-Query-DSL entwerfen“?

Erstellen Sie eine verkettbare Query-API, die sich selbst validiert. Du übst TypeScript Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um TypeScript Academy zu starten?

Keine Vorkenntnisse erforderlich. TypeScript Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Eine Fluent-Query-DSL entwerfen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser TypeScript Academy-Lektion Code schreiben und ausführen?

Ja. Jede TypeScript Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Was ist eine DSL auf Typebene
  2. Eine Fluent-Query-DSL entwerfen
  3. Eingabevalidierung zur Compile-Zeit
  4. Fehlermeldungen in DSLs auf Typebene
← Zurück zu TypeScript Academy