React Academy · บทเรียน

ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์

สร้างแบบจำลอง prop ของรูปแบบด้วยยูเนียนแบบแยกแยะ เพื่อให้ TypeScript บังคับใช้ชุด prop ที่ถูกต้อง

บทเรียน 1 จาก 413 ขั้นตอน

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

ปัญหาของพร็อพแบบรูปแบบ

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

ยูเนียนแบบมีตัวจำแนกคืออะไร

ยูเนียนแบบมีตัวจำแนกคือยูเนียนของชนิดที่ใช้ฟิลด์ชนิดค่าคงตัวร่วมกัน โดยฟิลด์นั้นเรียกว่าตัวจำแนก TypeScript จะจำกัดชนิดให้แคบลงตามค่าของฟิลด์นั้น

type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'rectangle'; width: number; height: number };

function area(shape: Shape): number {
  if (shape.kind === 'circle') return Math.PI * shape.radius ** 2;
  return shape.width * shape.height; // TS knows width/height exist here
}

รูปแบบ Button เทียบกับลิงก์

กำหนดรูปแบบคอมโพเนนต์พหุรูปแบบด้วยยูเนียนแบบมีตัวจำแนกบนฟิลด์ as หรือ variant เพื่อบังคับให้แต่ละกรณีใช้พร็อพที่ถูกต้อง

type ButtonProps =
  | { as: 'button'; onClick: () => void; disabled?: boolean; children: React.ReactNode }
  | { as: 'a'; href: string; target?: string; children: React.ReactNode };

function ActionButton(props: ButtonProps) {
  if (props.as === 'button') {
    return <button onClick={props.onClick} disabled={props.disabled}>{props.children}</button>;
  }
  return <a href={props.href} target={props.target}>{props.children}</a>;
}

รูปแบบของคอมโพเนนต์การแจ้งเตือน

กำหนดรูปแบบคอมโพเนนต์การแจ้งเตือนให้มีข้อมูลที่จำเป็นแตกต่างกันตามประเภทความรุนแรงแต่ละแบบ

type AlertProps =
  | { type: 'success'; message: string }
  | { type: 'error'; message: string; onRetry: () => void }
  | { type: 'warning'; message: string; details?: string };

function Alert(props: AlertProps) {
  if (props.type === 'error') {
    return (
      <div className="alert error">
        <p>{props.message}</p>
        <button onClick={props.onRetry}>Retry</button>
      </div>
    );
  }
  return <div className={`alert ${props.type}`}>{props.message}</div>;
}

การจำกัดชนิดในตัวจัดการเหตุการณ์

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

type LoadingState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

function DataView<T>({ state }: { state: LoadingState<T> }) {
  if (state.status === 'loading') return <Spinner />;
  if (state.status === 'error') return <p>{state.error.message}</p>;
  if (state.status === 'success') return <pre>{JSON.stringify(state.data)}</pre>;
  return null;
}

การตรวจสอบครบทุกกรณีด้วย never

เพิ่มการตรวจสอบ never ในแขนงเริ่มต้น เพื่อให้เกิดข้อผิดพลาดของ TypeScript หากเพิ่มสมาชิกยูเนียนใหม่แต่ไม่ได้จัดการ

function assertNever(x: never): never {
  throw new Error('Unhandled case: ' + x);
}

function renderIcon(type: AlertProps['type']) {
  switch (type) {
    case 'success': return <CheckIcon />;
    case 'error': return <XIcon />;
    case 'warning': return <WarnIcon />;
    default: return assertNever(type); // TS error if a case is missing
  }
}

ยูเนียนแบบมีตัวจำแนกสำหรับการตอบกลับของเอพีไอ

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

type ApiResult<T> =
  | { ok: true; data: T }
  | { ok: false; error: string; code: number };

async function fetchUser(id: string): Promise<ApiResult<User>> {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) return { ok: false, error: 'Not found', code: res.status };
  return { ok: true, data: await res.json() };
}

ตัวป้องกันชนิดสำหรับการจำกัดชนิด

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

function isSuccess<T>(result: ApiResult<T>): result is { ok: true; data: T } {
  return result.ok === true;
}

const result = await fetchUser('1');
if (isSuccess(result)) {
  console.log(result.data.name); // TS knows data exists
}

หลีกเลี่ยงพร็อพเสริมจำนวนมาก

หากไม่ใช้ยูเนียนแบบมีตัวจำแนก คอมโพเนนต์จะสะสมพร็อพเสริมที่ใช้ได้เฉพาะในชุดค่าผสมบางแบบ ทำให้สับสนและไม่มีการตรวจชนิด ยูเนียนแบบมีตัวจำแนกจะกำจัดสถานะที่เป็นไปไม่ได้

// Bad: optional prop soup — invalid combos allowed:
interface BadProps {
  href?: string;
  onClick?: () => void;
  disabled?: boolean;
}

// Good: only valid combos via discriminated union:
type GoodProps =
  | { as: 'a'; href: string }
  | { as: 'button'; onClick: () => void; disabled?: boolean };

การประกอบยูเนียน

ใช้ & (อินเทอร์เซกชัน) เพื่อเพิ่มพร็อพที่ใช้ร่วมกันให้กับสมาชิกทุกตัวของยูเนียน

type BaseProps = { className?: string; children: React.ReactNode };

type ButtonVariant =
  | (BaseProps & { variant: 'primary'; onClick: () => void })
  | (BaseProps & { variant: 'link'; href: string });

การจำแนกขณะทำงาน

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

ตรวจสอบความเข้าใจ

ตัวจำแนกในยูเนียนแบบมีตัวจำแนกคืออะไร

สรุปทบทวน

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

เริ่มต้นได้ฟรี

เรียนรู้ React ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
88
บทเรียน
324

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

บทเรียน “ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์”

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

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

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

บทเรียน “ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ยูเนียนแบบแยกแยะสำหรับรูปแบบคอมโพเนนต์
  2. ชนิดแบบมีเงื่อนไขและชนิดแบบแมปใน React
  3. คอมโพเนนต์พหุรูปแบบด้วย Prop 'as'
  4. ฟอร์มปลอดภัยด้านชนิดข้อมูลและสัญญาผลตอบกลับ API
← กลับไปที่ React Academy