0Pricing
TypeScript Academy · บทเรียน

ตัวสร้างที่มีชนิดข้อมูลเข้มงวด

ออกแบบตัวสร้างแบบต่อสายที่สะสมตัวเลือกซึ่งมีชนิดข้อมูล ตรวจสอบขั้นตอนที่จำเป็นและชุดค่าผสมที่ถูกต้องด้วยเจเนอริกและชนิดข้อมูลแบบมีเงื่อนไข

ตัวสร้างที่มีชนิดข้อมูลเข้มงวด เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

บทนำ

เป้าหมาย: สร้าง APIs ที่เชื่อมต่อเป็นสายได้และเข้ารหัสความคืบหน้าไว้ในชนิดข้อมูล แต่ละขั้นจะส่งกลับสถานะใหม่ที่มีชนิดข้อมูลกำกับ จึงตรวจพบลำดับที่ไม่ถูกต้องขณะคอมไพล์

  • สะสมตัวเลือกไว้ในเจเนอริก
  • ควบคุมการเข้าถึงแต่ละขั้นด้วยแฟล็ก
  • รักษา DX ให้เรียบง่าย

แฟล็กสถานะ

แต่ละขั้นจะส่งกลับชนิดข้อมูลสถานะใหม่ ส่วน 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)

แยกชุดการผสมที่ซับซ้อนด้วยชนิดข้อมูลแบบมีเงื่อนไข เพื่อให้สายการทำงานสะอาดและเข้าใจง่าย

ตรวจสอบการกำกับลำดับของตัวสร้าง

ตรวจสอบอย่างรวดเร็ว: เราจะทำให้แน่ใจได้อย่างไรว่าเมธอด .method() ถูกเรียกก่อน .build()

ทบทวน

ทบทวน: ส่งต่อสถานะที่มีชนิดข้อมูลกำกับไปตามสายการทำงาน สะสมตัวเลือกในเจเนอริก และตรวจจับลำดับที่ไม่ถูกต้องขณะคอมไพล์

คำถามที่พบบ่อย

บทเรียน “ตัวสร้างที่มีชนิดข้อมูลเข้มงวด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวสร้างที่มีชนิดข้อมูลเข้มงวด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวสร้างที่มีชนิดข้อมูลเข้มงวด”

ออกแบบตัวสร้างแบบต่อสายที่สะสมตัวเลือกซึ่งมีชนิดข้อมูล ตรวจสอบขั้นตอนที่จำเป็นและชุดค่าผสมที่ถูกต้องด้วยเจเนอริกและชนิดข้อมูลแบบมีเงื่อนไข คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน

บทเรียน “ตัวสร้างที่มีชนิดข้อมูลเข้มงวด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. สมาชิก rest ของทูเพิลและชนิดข้อมูลเคอร์รี
  2. ประกอบฟังก์ชันและอาร์กิวเมนต์อย่างปลอดภัย
  3. ตัวสร้างที่มีชนิดข้อมูลเข้มงวด
← กลับไปที่ TypeScript Academy