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

การเรียกซ้ำระดับชนิดข้อมูล

วนซ้ำผ่านชนิดข้อมูลด้วยชนิดข้อมูลแบบมีเงื่อนไขที่เรียกซ้ำ

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

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

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