การเรียกซ้ำระดับชนิดข้อมูล
วนซ้ำผ่านชนิดข้อมูลด้วยชนิดข้อมูลแบบมีเงื่อนไขที่เรียกซ้ำ
การเรียกซ้ำระดับชนิดข้อมูล เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
การเรียกซ้ำในชนิดข้อมูล
ชนิดข้อมูลแบบมีเงื่อนไขสามารถอ้างถึง ตัวมันเอง ได้ ทำให้ภาษาชนิดข้อมูลมีลูป การเรียกซ้ำระดับชนิดข้อมูลส่วนใหญ่จะเดินผ่าน ทูเพิล ทีละสมาชิก โดยแยกสมาชิกหัวออกแล้วเรียกซ้ำกับส่วนท้าย
type Length<T extends unknown[]> =
T extends [unknown, ...infer Rest]
? Length<Rest>
: 0;
// (this counts down to a base case)กรณีฐาน
การเรียกซ้ำทุกครั้งต้องมี เงื่อนไขหยุด สำหรับทูเพิล โดยปกติคือทูเพิลว่าง เมื่อรูปแบบ [head, ...rest] ไม่ตรงอีกต่อไป แสดงว่าถึงจุดสิ้นสุดแล้ว และให้ส่งคืนผลลัพธ์ที่กำหนดไว้
type IsEmpty<T extends unknown[]> =
T extends [] ? true : false;
type A = IsEmpty<[]>; // true
type B = IsEmpty<[1, 2]>; // falseส่วนหัวและส่วนท้าย
การดำเนินการหลักคือแยกทูเพิลออกเป็นสมาชิกตัวแรกและทูเพิลส่วนที่เหลือ โดยใช้ infer ร่วมกับรูปแบบการกระจาย
type Head<T extends unknown[]> = T extends [infer H, ...unknown[]] ? H : never;
type Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : [];
type A = Head<[1, 2, 3]>; // 1
type B = Tail<[1, 2, 3]>; // [2, 3]ประมวลผลทีละสมาชิก
รวมส่วนหัว ส่วนท้าย และการเรียกซ้ำเข้าด้วยกันเพื่อแปลงทูเพิลทั้งชุด ToStrings จะสร้างทูเพิลขึ้นใหม่ โดยแทนที่ชนิดข้อมูลของแต่ละสมาชิกด้วย string
type ToStrings<T extends unknown[]> =
T extends [infer H, ...infer R]
? [string, ...ToStrings<R>]
: [];
type A = ToStrings<[1, true, 3]>; // [string, string, string]รูปแบบตัวสะสม
บ่อยครั้งคุณจะสร้างผลลัพธ์ทีละน้อยในพารามิเตอร์เพิ่มเติมที่เรียกว่า ตัวสะสม ตัวสะสมจะเริ่มต้นเป็นค่าว่างและขยายขึ้นในแต่ละขั้น วิธีนี้หลีกเลี่ยงการเดินผ่านโครงสร้างซ้ำ และเป็นเทคนิคมาตรฐานสำหรับลูประดับชนิดข้อมูล
type Reverse<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? Reverse<R, [H, ...Acc]>
: Acc;
type A = Reverse<[1, 2, 3]>; // [3, 2, 1]การเดินผ่านตัวสะสม
ติดตามการทำงานของ Reverse<[1,2,3]>:
- ขั้นที่ 1: H=1 ตัวสะสมกลายเป็น [1]
- ขั้นที่ 2: H=2 ตัวสะสมกลายเป็น [2,1]
- ขั้นที่ 3: H=3 ตัวสะสมกลายเป็น [3,2,1]
- ทูเพิลว่าง ให้ส่งคืนตัวสะสม = [3,2,1]
ตัวสะสมจะนำคำตอบติดตัวไปในการเรียกซ้ำแต่ละครั้ง
type R = Reverse<["a", "b"]>; // ["b", "a"]การเรียกซ้ำบนยูเนียน
คุณยังสามารถเรียกซ้ำเพื่อรวมสตริงหลายค่าเข้าด้วยกันได้ ในที่นี้ เราต่อสมาชิกของทูเพิลให้เป็นชนิดข้อมูลลิเทอรัลสตริงหนึ่งชนิด โดยคั่นด้วยตัวแบ่ง
สัญกรณ์: TypeScript จริงจะเขียนชนิดข้อมูลลิเทอรัลแม่แบบด้วยสตริงที่คั่นด้วยเครื่องหมายย้อนกลับและมีช่องแทนค่าด้วยดอลลาร์กับวงเล็บปีกกา ในตัวอย่างเหล่านี้ เราแสดงรูปแบบดังกล่าวเป็น Tpl<...> โดยเรียงส่วนต่าง ๆ ตามลำดับ เช่น แม่แบบเครื่องหมายย้อนกลับที่ตรงกับคำนำหน้าลิเทอรัลแล้วตามด้วย Rest จะแสดงเป็น Tpl<'prefix', infer Rest>
type Join<T extends string[], Sep extends string = ','> =
T extends [infer H extends string, ...infer R extends string[]]
? R extends []
? H
: Tpl<H, Sep, Join<R, Sep>>
: '';
// Tpl<H, Sep, ...> builds a template literal type joining the parts
type A = Join<['a', 'b', 'c']>; // 'a,b,c'การนับด้วยการเรียกซ้ำ
การเรียกซ้ำร่วมกับตัวสะสมสามารถใช้สำหรับการนับได้ ให้สร้างทูเพิลของ unknown ที่มีความยาวเท่ากับอินพุต แล้วอ่านค่า length ของทูเพิลนั้นในภายหลัง คุณจะใช้วิธีนี้อย่างมากในหลักสูตรเลขคณิต
type Count<T extends unknown[], Acc extends unknown[] = []> =
T extends [unknown, ...infer R]
? Count<R, [unknown, ...Acc]>
: Acc["length"];
type A = Count<["x", "y", "z"]>; // 3การกรองด้วยการเรียกซ้ำ
เดินผ่านทูเพิลและเก็บไว้เฉพาะสมาชิกที่ตรงตามเงื่อนไข โดยทิ้งสมาชิกอื่นไป หากต้องการข้ามสมาชิก ให้ไม่เพิ่มสมาชิกนั้นลงในตัวสะสม
type KeepStrings<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? H extends string
? KeepStrings<R, [...Acc, H]>
: KeepStrings<R, Acc>
: Acc;
type A = KeepStrings<[1, "a", 2, "b"]>; // ["a", "b"]ขีดจำกัดความลึกของการเรียกซ้ำ
คอมไพเลอร์จำกัดความลึกของการเรียกซ้ำ (ในอดีตอยู่ที่ประมาณ 50 แต่การปรับให้เหมาะสมสำหรับการเรียกซ้ำแบบหางช่วยให้รูปแบบบางอย่างทำได้มากกว่านั้น) สำหรับทูเพิลที่มีขนาดใหญ่มาก คุณอาจพบข้อผิดพลาด การสร้างอินสแตนซ์ชนิดข้อมูลลึกเกินไป ให้ใช้รูปแบบตัวสะสม (แบบหาง) เพื่อเพิ่มขีดจำกัด
type Repeat<T, N extends number, Acc extends T[] = []> =
Acc["length"] extends N ? Acc : Repeat<T, N, [...Acc, T]>;
type A = Repeat<0, 3>; // [0, 0, 0]นำทุกอย่างมารวมกัน
การแยกส่วนหัวกับส่วนท้าย กรณีฐาน และตัวสะสม คือองค์ประกอบสามอย่างของลูประดับชนิดข้อมูลแทบทุกชนิด ด้วยองค์ประกอบเหล่านี้ คุณสามารถแมป กรอง กลับลำดับ นับ และรวมทูเพิลได้ทั้งหมดภายในระบบชนิดข้อมูล
type MapToPairs<T extends unknown[], Acc extends unknown[] = []> =
T extends [infer H, ...infer R]
? MapToPairs<R, [...Acc, [H, H]]>
: Acc;
type A = MapToPairs<[1, 2]>; // [[1, 1], [2, 2]]ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับรูปแบบตัวสะสม
ทบทวน
ตอนนี้คุณสามารถเขียนลูปในระดับชนิดข้อมูลได้แล้ว
- เงื่อนไขที่อ้างถึงตัวเองจะสร้างการเรียกซ้ำ
- แยกทูเพิลเป็น
[H, ...R]แล้วเรียกซ้ำกับส่วนท้าย - กรณีฐาน (ทูเพิลว่าง) จะหยุดลูป
- ตัวสะสมจะสร้างผลลัพธ์และช่วยให้เรียกซ้ำได้ลึกขึ้น
ถัดไป: วิธีที่เงื่อนไขทำงานเป็นพิเศษกับยูเนียน
คำถามที่พบบ่อย
บทเรียน “การเรียกซ้ำระดับชนิดข้อมูล” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเรียกซ้ำระดับชนิดข้อมูล” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเรียกซ้ำระดับชนิดข้อมูล”
วนซ้ำผ่านชนิดข้อมูลด้วยชนิดข้อมูลแบบมีเงื่อนไขที่เรียกซ้ำ คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การเรียกซ้ำระดับชนิดข้อมูล” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิดข้อมูลในฐานะภาษาการคำนวณ
- เงื่อนไขระดับชนิดข้อมูล
- การเรียกซ้ำระดับชนิดข้อมูล
- ชนิดข้อมูลแบบมีเงื่อนไขกระจาย