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

ชนิดข้อมูลแบบมีเงื่อนไขกระจาย

ควบคุมวิธีที่เงื่อนไขกระจายไปบนยูเนียน

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

พฤติกรรมที่น่าประหลาดใจ

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

นี่คือพื้นฐานของ Exclude, Extract และตัวช่วยอีกมากมาย

type ToArray<T> = T extends unknown ? T[] : never;

type A = ToArray<string | number>;
// string[] | number[]  (NOT (string | number)[])

ความหมายของคำว่า «เปลือย»

คำว่า «เปลือย» หมายถึงพารามิเตอร์ชนิดข้อมูลปรากฏอยู่ เพียงลำพัง ทางด้านซ้ายของ extends ไม่ได้ถูกห่อหุ้มอยู่ในชนิดข้อมูลอื่น การแจกแจงจะเกิดขึ้นเฉพาะกับพารามิเตอร์แบบเปลือยเท่านั้น

type Naked<T> = T extends string ? "y" : "n";
// T is naked -> distributes over unions

ขั้นตอนการแจกแจงทีละขั้น

สำหรับ ToArray<string | number> คอมไพเลอร์จะประเมินสมาชิกแต่ละตัว:

  • ToArray<string> = string[]
  • ToArray<number> = number[]

จากนั้นจึงรวมเป็นยูเนียน: string[] | number[]

type R = ToArray<boolean>;
// boolean is true | false, so:
// true[] | false[]

การกรองยูเนียน

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

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

type A = Strings<string | number | boolean>; // string

never หายไปในยูเนียน

ข้อเท็จจริงสำคัญคือ X | never จะถูกทำให้ง่ายลงเป็น X ดังนั้นเมื่อแขนงที่แจกแจงแล้วให้ผลเป็น never สมาชิกนั้นจะถูกนำออกจากยูเนียนสุดท้ายโดยปริยาย

type A = string | never;        // string
type B = "a" | never | "b";     // "a" | "b"

การปิดการแจกแจง

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

type IsNever<T> = [T] extends [never] ? true : false;

type A = IsNever<never>;  // true
type B = IsNever<string>; // false

เหตุผลที่การห่อใช้งานได้

เมื่อวาง [T] ไว้ทางด้านซ้าย ชนิดข้อมูลที่ตรวจสอบจะเป็นทูเพิล ไม่ใช่พารามิเตอร์เดี่ยว ๆ กฎพิเศษเรื่องการแจกแจงจึงไม่มีผลอีกต่อไป และยูเนียนจะถูกตรวจสอบทั้งชุด

type AllStrings<T> = [T] extends [string] ? true : false;

type A = AllStrings<"a" | "b">;     // true
type B = AllStrings<"a" | number>;  // false

แบบแจกแจงและไม่แจกแจง

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

type Distributed<T> = T extends string ? true : false;
type Wrapped<T> = [T] extends [string] ? true : false;

type A = Distributed<string | number>; // boolean (true | false)
type B = Wrapped<string | number>;     // false

เบื้องหลังของ Exclude

Exclude<T, U> ในตัวจะนำสมาชิกใด ๆ จาก T ที่สามารถกำหนดให้ใช้แทน U ได้ออกไป มันเป็นเพียงชนิดข้อมูลแบบมีเงื่อนไขที่แจกแจงสมาชิกที่ตรงกันให้เป็น never

type MyExclude<T, U> = T extends U ? never : T;

type A = MyExclude<"a" | "b" | "c", "b">; // "a" | "c"

เบื้องหลังของ Extract

Extract<T, U> เป็นภาพสะท้อนกลับของ Exclude: เก็บไว้เฉพาะสมาชิกที่สามารถกำหนดให้ใช้แทน U ได้ ใช้การแจกแจงแบบเดียวกัน แต่สลับแขนงกัน

type MyExtract<T, U> = T extends U ? T : never;

type A = MyExtract<"a" | "b" | "c", "a" | "c">; // "a" | "c"

พลังในการใช้งานจริง

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

สัญกรณ์: TypeScript จริงจะเขียนชนิดข้อมูลลิเทอรัลแม่แบบด้วยสตริงที่คั่นด้วยเครื่องหมายย้อนกลับและมีช่องแทนค่าด้วยดอลลาร์กับวงเล็บปีกกา ในตัวอย่างเหล่านี้ เราแสดงรูปแบบดังกล่าวเป็น Tpl<...> โดยเรียงส่วนต่าง ๆ ตามลำดับ เช่น แม่แบบเครื่องหมายย้อนกลับที่ตรงกับคำนำหน้าลิเทอรัลแล้วตามด้วย Rest จะแสดงเป็น Tpl<'prefix', infer Rest>

type Prefix<T extends string> = T extends unknown ? Tpl<'id_', T> : never;
// Tpl<'id_', T> is the template literal type joining 'id_' with each T

type A = Prefix<'a' | 'b'>; // 'id_a' | 'id_b'

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

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

ทบทวน

ชนิดข้อมูลแบบมีเงื่อนไขที่แจกแจงคือกลไกเบื้องหลังตัวช่วยสำหรับยูเนียน

  • T extends U ? แบบเปลือยจะแจกแจงผ่านสมาชิกแต่ละตัวของยูเนียน
  • แขนงที่ส่งคืน never จะกรองสมาชิกออก
  • [T] extends [U] จะปิดการแจกแจงเมื่อตรวจสอบยูเนียนทั้งชุด
  • Exclude และ Extract เป็นชนิดข้อมูลแบบมีเงื่อนไขที่แจกแจงขนาดเล็ก

ถัดไปในบทที่ 22: เลขคณิตในระบบชนิดข้อมูล

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

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

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

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

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

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

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

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

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

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

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

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

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