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

เงื่อนไขระดับชนิดข้อมูล

แยกแขนงตามชนิดข้อมูลด้วยนิพจน์ชนิดข้อมูลแบบมีเงื่อนไข

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

คำสั่งเงื่อนไขระดับชนิดข้อมูล

ภาษาชนิดข้อมูลมีการแตกแขนงด้วย ชนิดข้อมูลแบบมีเงื่อนไข ไวยากรณ์ T extends U ? X : Y มีความหมายว่า หาก T สามารถกำหนดค่าให้ใช้แทน U ได้ ผลลัพธ์คือ X มิฉะนั้นคือ Y

นี่คือสิ่งที่เทียบเท่ากับนิพจน์ if / else ในระดับชนิดข้อมูล

type IsString<T> = T extends string ? "yes" : "no";

type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"

ความสัมพันธ์แบบขยายหมายถึงการกำหนดให้ใช้แทนกันได้

การทดสอบนี้ไม่ใช่การตรวจว่าค่าเท่ากัน T extends U เป็นจริงเมื่อค่าสักค่าที่มีชนิด T สามารถนำไปใช้ในตำแหน่งที่คาดว่าจะเป็น U ได้ ชนิดข้อมูลแบบลิเทอรัลสามารถกำหนดให้ใช้แทนชนิดข้อมูลพื้นฐานได้

type T1 = "hello" extends string ? true : false; // true
type T2 = string extends "hello" ? true : false; // false
type T3 = 42 extends number ? true : false;       // true

การเลือกชนิดผลลัพธ์

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

type Wrap<T> = T extends unknown[]
  ? { list: T }
  : { value: T };

type A = Wrap<number>;   // { value: number }
type B = Wrap<string[]>; // { list: string[] }

การกรองให้เหลือชนิดที่ไม่มีค่า

เทคนิคที่ใช้กันทั่วไปคือส่งคืน never ในแขนงหนึ่ง never หมายถึง «ไม่มีค่า» และมีประโยชน์สำหรับนำสมาชิกออกจากยูเนียนในภายหลัง

type OnlyStrings<T> = T extends string ? T : never;

type A = OnlyStrings<string>; // string
type B = OnlyStrings<number>; // never

การอนุมานชนิดข้อมูล

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

ในที่นี้ เราเก็บชนิดข้อมูลของสมาชิกอาร์เรย์

type ElementType<T> = T extends (infer U)[] ? U : never;

type A = ElementType<number[]>; // number
type B = ElementType<string[]>; // string

การอนุมานผลลัพธ์ของฟังก์ชัน

คุณสามารถวาง infer ไว้ที่ใดก็ได้ในรูปแบบ หากต้องการแยกชนิดผลลัพธ์ของฟังก์ชัน ให้อนุมานส่วนที่อยู่หลังลูกศร นี่คือวิธีการทำงานของ ReturnType ในตัว

type MyReturn<T> = T extends (...args: any[]) => infer R ? R : never;

type A = MyReturn<() => number>;      // number
type B = MyReturn<(x: string) => boolean>; // boolean

การอนุมานหลายส่วน

เงื่อนไขเดียวสามารถสร้างตัวแปร infer หลายตัวพร้อมกันได้ ในที่นี้ เราดึงทั้งส่วนแรกและส่วนที่เหลือของทูเพิลออกมา

type FirstRest<T> = T extends [infer H, ...infer R]
  ? { head: H; rest: R }
  : never;

type A = FirstRest<[1, 2, 3]>;
// { head: 1; rest: [2, 3] }

เงื่อนไขซ้อนกัน

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

type Describe<T> =
  T extends string ? "text" :
  T extends number ? "num" :
  T extends boolean ? "flag" :
  "other";

type A = Describe<number>; // "num"
type B = Describe<null>;   // "other"

เงื่อนไขในฐานะเครื่องป้องกัน

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

type GetName<T> = T extends { name: infer N } ? N : never;

type A = GetName<{ name: string }>; // string
type B = GetName<{ age: number }>;  // never

การรวมเงื่อนไข

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

type RequireId<T> =
  T extends object
    ? T extends { id: unknown } ? T : never
    : never;

type A = RequireId<{ id: 1; x: 2 }>; // { id: 1; x: 2 }
type B = RequireId<{ x: 2 }>;        // never

ชนิดข้อมูลแบบมีเงื่อนไขอยู่ทุกที่

ชนิดข้อมูลตัวช่วยในตัวส่วนใหญ่ล้วนเป็นชนิดข้อมูลแบบมีเงื่อนไขที่อยู่เบื้องหลัง ได้แก่ NonNullable, Extract, Exclude, Parameters และ ReturnType การทำความเข้าใจ extends ? : จะช่วยให้คุณใช้สิ่งเหล่านี้ได้ทั้งหมด

type MyNonNullable<T> = T extends null | undefined ? never : T;

type A = MyNonNullable<string | null>; // string

ตรวจสอบความเข้าใจอย่างรวดเร็ว

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

ทบทวน

ชนิดข้อมูลแบบมีเงื่อนไขช่วยเพิ่มคำสั่ง if/else และการจับคู่รูปแบบให้แก่ภาษาชนิดข้อมูล

  • T extends U ? X : Y จะแตกแขนงตามความสามารถในการกำหนดค่าให้ใช้แทนกันได้
  • infer จะเก็บส่วนที่ตรงกับรูปแบบไว้ในตัวแปรใหม่
  • เงื่อนไขสามารถซ้อนกันเพื่อสร้างลำดับการตัดสินใจ
  • การส่งคืน never จะกรองสมาชิกออก

ถัดไป: ป้อนเงื่อนไขกลับเข้าไปในตัวมันเองเพื่อทำ การเรียกซ้ำ

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

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

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

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

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

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

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

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

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

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

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

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

  1. ชนิดข้อมูลในฐานะภาษาการคำนวณ
  2. เงื่อนไขระดับชนิดข้อมูล
  3. การเรียกซ้ำระดับชนิดข้อมูล
  4. ชนิดข้อมูลแบบมีเงื่อนไขกระจาย
← กลับไปที่ TypeScript Academy