TypeScript Academy · Lektion

Stærkt typede builders

Design kædede builders, der opsamler typede indstillinger, og sikr påkrævede trin og gyldige kombinationer med generics og betingede typer.

Lektion 3 af 38 trin

Stærkt typede builders er en gratis TypeScript Academy-lektion på CoddyKit. Dette er lektion 3 af 3. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i TypeScript Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. TypeScript Academy-kurset indeholder 3 lektioner i alt.

Introduktion

Mål: Byg kædebare API'er, der indkoder fremdrift i typen. Hvert trin returnerer en ny typet tilstand, så ugyldige rækkefølger fejler under kompilering.

  • Akkumulér indstillinger i en generisk type
  • Styr trin med flag
  • Hold udvikleroplevelsen enkel

Tilstandsflag

Hvert trin returnerer en ny tilstandstype; build er kun tilgængelig, når de krævede flag er true.

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

Akkumulér indstillinger

Akkumulér indstillinger i O-generikken; hvert kald returnerer en type, der tilføjer nye egenskaber.

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()

Gyldige kombinationer

Begræns kombinationer med betingede typer: gør body tilgængelig kun for 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

Variadisk behandlingskæde

Saml trin som en samling af variadiske tupler; håndtér inddata og uddata med 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

Tips

Tips:

Hold tilstanden som en phantom-generisk type; belast ikke kørselstiden.

Hold trinnavn korte og faste (method, url).

Adskil vanskelige kombinationer med betingede typer; hold kæden ren.

Tjek af builder-styring

Hurtigt tjek: Hvordan sikrer vi, at .method() kaldes før .build()?

Opsummering

Opsummering: Før typet tilstand med gennem kæden, akkumulér indstillinger i generiske typer, og fang ugyldige sekvenser under kompilering.

Gratis at komme i gang

Lær TypeScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
101
Lektioner
352

Ofte stillede spørgsmål

Er lektionen “Stærkt typede builders” gratis?

Ja — hele teksten til “Stærkt typede builders” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af TypeScript Academy-kurset, skal du opgradere til CoddyKit PRO. TypeScript Academy-kurset indeholder 3 lektioner i alt.

Hvad lærer jeg i “Stærkt typede builders”?

Design kædede builders, der opsamler typede indstillinger, og sikr påkrævede trin og gyldige kombinationer med generics og betingede typer. Du øver dig i TypeScript Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på TypeScript Academy?

Der kræves ingen tidligere erfaring. TypeScript Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 3.

Hvor lang tid tager lektionen “Stærkt typede builders”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne TypeScript Academy-lektion?

Ja. Alle TypeScript Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Tuple-rest-elementer og curry-typer
  2. Sikker sammensætning af funktioner og argumenter
  3. Stærkt typede builders
← Tilbage til TypeScript Academy