เงื่อนไขระดับชนิดข้อมูล
แยกแขนงตามชนิดข้อมูลด้วยนิพจน์ชนิดข้อมูลแบบมีเงื่อนไข
เงื่อนไขระดับชนิดข้อมูล เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิดข้อมูลในฐานะภาษาการคำนวณ
- เงื่อนไขระดับชนิดข้อมูล
- การเรียกซ้ำระดับชนิดข้อมูล
- ชนิดข้อมูลแบบมีเงื่อนไขกระจาย