0Pricing
TypeScript Academy · レッスン

Fluent Query DSLの設計

連鎖可能で自己検証するクエリAPIを構築します。

「Fluent Query DSLの設計」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

Fluent Query DSL の設計

各ステップの戻り値の型によって次に許可されるステップを絞り込む、連鎖可能なクエリ DSL を設計します。結果は SQL のように読め、無効な順序はコンパイル時に拒否されます。

対象とする文法

目標は、from、続いて任意の where(繰り返し可能)、最後に終端の select という順序です。from の前に select を呼び出すことはできず、from を 2 回呼び出すこともできません。

状態インターフェース

各段階を、次の段階を返すインターフェースとしてモデル化します。

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

順序を強制する

select は FromStage にのみ存在するため、初期状態の Builder で呼び出すとコンパイルエラーになります。各段階が公開するメソッドだけによって、順序が適用されます。

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

選択したカラムを追跡する

選択したカラムを記録するファントムジェネリックを追加し、結果の型を正確にします。

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[]; }

呼び出すたびに型を絞り込む

各 where で制約を型に蓄積することもできます。ここでは単純にしていますが、このパターンはバインドしたパラメーターの追跡にも一般化できます。

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

from の繰り返しを防ぐ

FromStage は from を公開していないため、2 回呼び出すことはできません。文法によって構造的に禁止されるので、実行時のガードは必要ありません。

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

終端ステップ

select は Result を返します。Result は where も from も公開しないため、チェーンはここで終了します。残るのは結果を読み取る操作だけです。

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

型付きカラム制約

別のジェネリックを使ってカラムを既知のテーブルスキーマに制約し、未知のカラムを拒否します。これにより、この DSL と前のレッスンで扱った ORM の考え方を組み合わせられます。

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

任意ステップと必須ステップ

次のメソッドをステップの後でのみ公開することで、そのステップを必須にできます。たとえば、where の呼び出し後にだけ select が現れるステージを返せば、少なくとも 1 回の where を強制できます。同じ連鎖型でクエリを実行したときの結果行の型も推論できるため、コンパイル時の文法と実行時のデータを結び付けられます。

これが重要な理由

このように設計した Fluent DSL は自己文書化され、誤用できません。オートコンプリートには有効な次のステップだけが表示され、違法な順序は決してコンパイルできないためです。これは使いやすいビルダーライブラリの基盤となります。

クイックチェック

Fluent DSL の設計についての理解度を確認します。

まとめ

Fluent query DSL を型レベルのステートマシンとして設計しました。各段階のインターフェースは次の段階を返し、有効なメソッドだけを公開します。ファントムジェネリックで選択したカラムを追跡し、終端段階でチェーンを終了し、カラム制約で未知の名前を拒否します。これらはすべて戻り値の型によって適用されます。

よくある質問

「Fluent Query DSLの設計」レッスンは無料ですか?

はい。「Fluent Query DSLの設計」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「Fluent Query DSLの設計」で何を学びますか?

連鎖可能で自己検証するクエリAPIを構築します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Fluent Query DSLの設計」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型レベルDSLとは
  2. Fluent Query DSLの設計
  3. コンパイル時の入力バリデーション
  4. 型レベルDSLのエラーメッセージ
← TypeScript Academyに戻る