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

ชนิดแบบ Result/Either

จำลองความสำเร็จและความล้มเหลวอย่างชัดเจนด้วยยูเนียน Result/Either เพิ่มตัวช่วย (map/flatMap/mapError) และทำให้ลำดับการทำงานคาดเดาได้โดยไม่ต้องใช้ try/catch ทุกแห่ง

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

บทนำ

เป้าหมาย: ทำให้ความล้มเหลวมองเห็นได้ คุณจะจำลองผลลัพธ์ด้วยยูเนียนแบบแยกประเภท ประกอบการทำงานด้วยตัวช่วย และแปลงข้อยกเว้นที่ขอบเขตระบบ

  • ชนิด Result
  • map/flatMap/mapError
  • การเชื่อมต่อกับ HTTP

แกนหลักของ Result

สร้างยูทิลิตี Result ขนาดเล็ก: ตัวสร้าง ok/err พร้อม map, flatMap, mapError สำหรับการประกอบการทำงาน

export type Ok<T>  = { ok: true;  value: T }
export type Err<E> = { ok: false; error: E }
export type Result<T, E> = Ok<T> | Err<E>

export const ok = <T>(value: T): Ok<T> => ({ ok: true, value })
export const err = <E>(error: E): Err<E> => ({ ok: false, error })

export function map<T, E, U>(r: Result<T, E>, f: (t: T) => U): Result<U, E> {
  return r.ok ? ok(f(r.value)) : r
}
export function flatMap<T, E, U>(r: Result<T, E>, f: (t: T) => Result<U, E>): Result<U, E> {
  return r.ok ? f(r.value) : r
}
export function mapError<T, E, F>(r: Result<T, E>, g: (e: E) => F): Result<T, F> {
  return r.ok ? r : err(g(r.error))
}

ข้อผิดพลาดระดับโดเมน

จำลอง ข้อผิดพลาดระดับโดเมน เป็นยูเนียนแบบแยกประเภทพร้อม tag แต่ละแขนงจะเก็บข้อมูลที่แม่นยำเพื่อสร้างข้อความที่ดี

export type CreateUserError =
  | { tag: "InvalidEmail"; detail?: string }
  | { tag: "Duplicate"; email: string }

export function validateEmail(email: string): Result<string, CreateUserError> {
  const okEmail = /.+@.+/.test(email)
  return okEmail ? ok(email.toLowerCase()) : err({ tag: "InvalidEmail", detail: "bad format" })
}

const existing = new Set(["ada@example.com"]) // pretend DB
export function saveUser(email: string): Result<{ id: string }, CreateUserError> {
  if (existing.has(email)) return err({ tag: "Duplicate", email })
  return ok({ id: Math.random().toString(36).slice(2) })
}

การประกอบลำดับการทำงาน

ประกอบการตรวจสอบเข้าด้วยกันด้วย flatMap ใช้คำสั่ง switch พร้อมการตรวจสอบ never เพื่อบังคับให้จัดการครบทุกกรณีขณะคอมไพล์

export function createUser(flowEmail: string) {
  return flatMap(validateEmail(flowEmail), email => saveUser(email))
}

// Use
const r = createUser("Ada@example.com")
if (r.ok) {
  console.log("id:", r.value.id)
} else {
  switch (r.error.tag) {
    case "InvalidEmail": console.error("invalid email:", r.error.detail); break
    case "Duplicate": console.error("already used:", r.error.email); break
    default: ((x: never) => x)(r.error) // exhaustiveness
  }
}

ข้อยกเว้น → Result

ที่ขอบเขตการรับส่งข้อมูล ให้ห่อข้อยกเว้นและแปลงเป็น Result ผู้เรียกใช้จะมีเส้นทางจัดการข้อผิดพลาดเพียงเส้นทางเดียว

export async function fromPromise<T>(p: Promise<T>): Promise<Result<T, { tag: "Exception"; message: string }>> {
  try { return ok(await p) }
  catch (e) { return err({ tag: "Exception", message: e instanceof Error ? e.message : String(e) }) }
}

// Example: wrap a fetch
export async function fetchJson<T>(url: string): Promise<Result<T, { tag: "Exception"; message: string }>> {
  return fromPromise(fetch(url).then(r => r.json() as T))
}

เคล็ดลับการแมป HTTP

การเชื่อมต่อกับ HTTP: แมปข้อผิดพลาดระดับโดเมนเป็น 400/409 และข้อยกเว้นจากการรับส่งข้อมูลเป็น 502/503 ใช้ฟังก์ชันแมปขนาดเล็กเพื่อให้ตัวควบคุมสะอาดและคาดเดาได้

การตรวจสอบประโยชน์ของ Result

ตรวจสอบอย่างรวดเร็ว: เหตุใดจึงควรใช้ยูเนียน Result แบบแยกประเภท

สรุปทบทวน

สรุปทบทวน: กำหนดชนิด Result ขนาดเล็ก ประกอบการทำงานด้วย map/flatMap จำลองข้อผิดพลาดระดับโดเมนเป็นยูเนียน และแปลงข้อยกเว้นที่ขอบเขตระบบ

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

บทเรียน “ชนิดแบบ Result/Either” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ชนิดแบบ Result/Either”

จำลองความสำเร็จและความล้มเหลวอย่างชัดเจนด้วยยูเนียน Result/Either เพิ่มตัวช่วย (map/flatMap/mapError) และทำให้ลำดับการทำงานคาดเดาได้โดยไม่ต้องใช้ try/catch ทุกแห่ง คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

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

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

บทเรียน “ชนิดแบบ Result/Either” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ชนิดแบบ Result/Either
  2. การจัดการข้อผิดพลาดแบบครอบคลุมด้วยยูเนียนที่จำแนกประเภท
← กลับไปที่ TypeScript Academy