0Pricing
TypeScript Academy · レッスン

厳密に型付けされたビルダー

型付きオプションを蓄積するチェーン可能なビルダーを設計し、ジェネリクスとConditional Typesで必須手順と有効な組み合わせを保証します

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

概要

目標: 進行状況を型に記録するチェーン可能な API を構築します。各ステップが新しい型付きの状態を返すため、無効な順序はコンパイル時に失敗します。

  • ジェネリックにオプションを蓄積する
  • フラグでステップを制御する
  • DX をシンプルに保つ

状態フラグ

各ステップは新しい状態の型を返します。必要なフラグが true の場合にのみ build を使用できます。

type Flags = { method: boolean; url: boolean }

type With<F extends Partial<Flags>> = { flags: F }

type True = true

type Builder<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  method<M extends "GET" | "POST">(m: M): Builder<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): Builder<F & { url: True }, O & { url: U }>
  build(this: Builder<{ method: True; url: True }, any>): O
}

function createBuilder(): Builder<{}, {}> {
  return {
    flags: {},
    method(m) { return { ...this, flags: { ...this.flags, method: true }, method: this.method, url: this.url, build: this.build } as any },
    url(u) { return { ...this, flags: { ...this.flags, url: true }, method: this.method, url: this.url, build: this.build } as any },
    build() { return this as any }
  } as any
}

const b = createBuilder()
const good = b.method("GET").url("/users").build()   // ok
// const bad = b.build() // error: build requires method & url flags

オプションを蓄積

O ジェネリックにオプションを蓄積します。呼び出すたびに、新しいプロパティを追加した型が返されます。

type B2<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  header<K extends string, V extends string>(k: K, v: V): B2<F, O & { headers: Record<K, V> }>
  query<K extends string, V extends string>(k: K, v: V): B2<F, O & { query: Record<K, V> }>
  method<M extends "GET" | "POST">(m: M): B2<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): B2<F & { url: True }, O & { url: U }>
  build(this: B2<{ method: True; url: True }, any>): O
}

function builder2(): B2<{}, {}> { return {} as any }

const conf = builder2()
  .method("POST")
  .url("/login")
  .header("x-id", "42")
  .query("next", "home")
  .build()

有効な組み合わせ

条件型で組み合わせを制限します。body は POST の場合にのみ自由に指定できるようにします。

type Method = "GET" | "POST"

type BodyIfPost<M extends Method, B> = M extends "POST" ? { body: B } : {}

type B3<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  method<M extends Method>(m: M): B3<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): B3<F & { url: True }, O & { url: U }>
  body<B>(b: B & (O extends { method: "POST" } ? unknown : never)): B3<F, O & BodyIfPost<O extends { method: infer M } ? Extract<M, Method> : Method, B>>
  build(this: B3<{ method: True; url: True }, any>): O
}

function builder3(): B3<{}, {}> { return {} as any }

const ok = builder3().method("POST").url("/u").body({ a: 1 }).build()
// const badBody = builder3().method("GET").url("/u").body({ a: 1 }).build() // compile-time error

可変長パイプライン

可変長タプル配列でステップをコレクションとしてまとめます。Parameters/ReturnType を使って入力と出力を管理します。

type Step<A extends any[], R> = (...args: A) => R

type Pipeline<P extends Step<any, any>[]> = {
  use<S extends Step<any, any>>(...s: [S]): Pipeline<[...P, S]>
  run<A extends Parameters<P[0]>>(this: Pipeline<P>, ...args: A): ReturnType<P[number]>
}

function pipeMake(): Pipeline<[]> { return {} as any }

const pipe = pipeMake()
  .use((a: string) => a.length)
  .use((n: number) => n % 2 === 0)
// pipe.run("abc") // demo; implementation omitted

ヒント

ヒント:

状態はファントムジェネリックとして保持し、実行時に負担をかけないようにしてください。

ステップ名は短く固定してください(method、url)。

難しい組み合わせは条件型で分離し、チェーンを整理してください。

ビルダーの制御を確認

簡単な確認: .build() の前に .method() が呼び出されることをどのように保証しますか。

振り返り

振り返り: 型付きの状態をチェーンに沿って渡し、ジェネリックにオプションを蓄積することで、無効な順序をコンパイル時に検出できます。

よくある質問

「厳密に型付けされたビルダー」レッスンは無料ですか?

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

「厳密に型付けされたビルダー」で何を学びますか?

型付きオプションを蓄積するチェーン可能なビルダーを設計し、ジェネリクスとConditional Typesで必須手順と有効な組み合わせを保証します ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「厳密に型付けされたビルダー」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. タプルのrest要素、curryの型
  2. 関数と引数を安全に合成する
  3. 厳密に型付けされたビルダー
← TypeScript Academyに戻る