厳密に型付けされたビルダー
型付きオプションを蓄積するチェーン可能なビルダーを設計し、ジェネリクスと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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- タプルのrest要素、curryの型
- 関数と引数を安全に合成する
- 厳密に型付けされたビルダー