0Pricing
TypeScript Academy · درس

عمق التكرار وحدوده

افهموا قيود عمق التكرار في TypeScript

عمق التكرار وحدوده درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

لدى TypeScript حدود للتكرار

تتمتع الأنواع التكرارية بقدرات قوية، لكن مدقق الأنواع يحدّد مدى العمق الذي يمكنه عنده إنشاء مثيلات منها. وعند بلوغ الحد تظهر لك مشكلة متعلقة بالعمق.

// Excessively deep recursive types can produce:
// "Type instantiation is excessively deep and possibly infinite."

مصدر أخطاء العمق

يمكن للأنواع الشرطية التي تكرر نفسها من دون حالة أساسية واضحة ومتقلصة أن تدخل في تكرار لا نهائي، خصوصًا عند دمجها مع اتحادات كبيرة أو بناء الصفوف.

type Repeat<N extends number, Acc extends unknown[] = []> =
  Acc["length"] extends N ? Acc : Repeat<N, [...Acc, unknown]>;
// Large N can exceed the instantiation depth.
type Five = Repeat<5>;

تكرار محدود وآمن

حافظ على أن يكون التكرار سطحيًا ومحدودًا. لا بأس ببناء صف صغير؛ إذ توقفه الحالة الأساسية Acc["length"] extends N بسرعة.

type Tuple<N extends number, Acc extends unknown[] = []> =
  Acc["length"] extends N ? Acc : Tuple<N, [...Acc, unknown]>;
type Three = Tuple<3>; // [unknown, unknown, unknown]
const t: Three = [1, 2, 3];
console.log(t.length);

أنماط الأنواع ذات التكرار الذيلي

يحسّن TypeScript بعض الأنواع الشرطية ذات التكرار الذيلي من خلال تمرير مجمّع، مما يسمح بتكرار أعمق من التداخل الساذج.

type Reverse<T extends unknown[], Acc extends unknown[] = []> =
  T extends [infer Head, ...infer Tail]
    ? Reverse<Tail, [Head, ...Acc]>
    : Acc;
type R = Reverse<[1, 2, 3]>; // [3, 2, 1]
const r: R = [3, 2, 1];
console.log(r);

لماذا تساعد المجمّعات

يُبقي تمرير النتائج إلى الأمام في مجمّع عملية التكرار في الموضع الذيلي، حيث يستطيع TypeScript فكّها بكفاءة أكبر من الشروط المتداخلة بعمق.

type Join<T extends string[], Acc extends string = ""> =
  T extends [infer H extends string, ...infer R extends string[]]
    ? Join<R, Acc extends "" ? H : Acc>
    : Acc;
type First = Join<["a", "b", "c"]>; // "a"
const f: First = "a";
console.log(f);

تجنب التكرار غير الذيلي

يؤدي تغليف الاستدعاء التكراري داخل عملية نوع أخرى إلى إخراجه من الموضع الذيلي، وقد يؤدي إلى بلوغ الحدود في وقت أبكر. لذلك يُفضّل تمرير الحالة في مجمّع بدلًا من ذلك.

// Non-tail (can be costly): builds nesting around the recursive call
// type Bad<T> = T extends [infer H, ...infer R] ? [H, ...Bad<R>] : [];
// Tail-friendly alternative uses an accumulator parameter.
console.log("prefer accumulators");

تحديد حد العمق صراحةً

أضف عدّادًا للعمق حتى يتوقف النوع بعد عدد ثابت من المستويات، وبذلك تستبدل الشمولية بإنهاء مضمون.

type Flatten<T, Depth extends unknown[] = []> =
  Depth["length"] extends 5
    ? T
    : T extends (infer U)[]
      ? Flatten<U, [...Depth, unknown]>
      : T;
type X = Flatten<number[][]>; // number
const x: X = 7;
console.log(x);

العمق العملي يكون مناسبًا عادةً

لا تبلغ الأنواع التكرارية اليومية، مثل القوائم المرتبطة والأشجار وJSON، الحد عادةً لأن البيانات التي تنشئ مثيلًا لها سطحية. وتؤثر الحدود أساسًا في الحسابات الثقيلة على مستوى الأنواع.

type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const v: Json = { a: { b: { c: 1 } } }; // fine, shallow
console.log(v);

التعرف على رسالة الخطأ

عندما ترى الرسالة "excessively deep and possibly infinite"، ابحث عن حالة أساسية مفقودة، أو مجمّع في موضع غير ذيلي، أو مدخل كبير جدًا.

// Fixes: add/tighten the base case, switch to tail recursion,
// reduce input size, or cap with a depth counter.
console.log("check base case and tail position");

التكرار أثناء التشغيل منفصل

تتعلق هذه الحدود بالتكرار على مستوى الأنواع. أما الدوال التكرارية العادية التي تعمل على أنواع تكرارية فتُنفَّذ أثناء التشغيل، ولا يحدّها إلا مكدس الاستدعاءات.

type TreeNode<T> = { value: T; children: TreeNode<T>[] };
function count<T>(n: TreeNode<T>): number {
  return 1 + n.children.reduce((a, c) => a + count(c), 0);
}
console.log(count({ value: 1, children: [{ value: 2, children: [] }] }));

التصميم ضمن الحدود

فضّل البيانات قليلة العمق، وأنماط التكرار الذيلي باستخدام المجمّعات، وحدود العمق الصريحة. ومع اتباع هذه الممارسات، نادرًا ما تبلغ الحد في الشيفرة الواقعية.

type Length<T extends unknown[]> = T["length"];
type N = Length<[1, 2, 3]>; // 3
const n: N = 3;
console.log(n);

تحقق سريع: حدود التكرار

اختبر مدى فهمك لعمق التكرار وحدوده.

مراجعة: عمق التكرار وحدوده

تعلمت أن TypeScript يحدّ عمق التكرار على مستوى الأنواع، وأن أنماط التكرار الذيلي مع المجمّعات وحدود العمق الصريحة تساعد على تجنب ذلك، وأن البيانات التكرارية اليومية نادرًا ما تبلغ الحد.

type Reverse<T extends unknown[], Acc extends unknown[] = []> =
  T extends [infer H, ...infer R] ? Reverse<R, [H, ...Acc]> : Acc;
const r: Reverse<[1, 2]> = [2, 1];
console.log(r);

الأسئلة الشائعة

هل درس «عمق التكرار وحدوده» مجاني؟

نعم — نص درس «عمق التكرار وحدوده» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «عمق التكرار وحدوده»؟

افهموا قيود عمق التكرار في TypeScript تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «عمق التكرار وحدوده»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تعريفات الأنواع التكرارية
  2. تحديد أنواع هياكل الأشجار
  3. أنواع قيم JSON
  4. عمق التكرار وحدوده
← العودة إلى TypeScript Academy