0Pricing
TypeScript Academy · درس

الأنواع الشرطية التوزيعية

تحكموا في كيفية توزيع الشروط على الاتحادات

الأنواع الشرطية التوزيعية درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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> هو الصورة المعاكسة: يحتفظ فقط بالأعضاء القابلة للإسناد إلى U. التوزيع نفسه، لكن الفرعين متعاكسان.

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

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

القوة العملية

يتيح لك التوزيع تحويل كل عضو في اتحاد ضمن تعبير واحد: إنشاء مصفوفات لكل عضو، أو إضافة بادئة إلى كل سلسلة نصية، أو التصفية حسب البنية. وبدمجه مع [T] extends [U] لفحص الاتحاد بأكمله، تتحكم بدقة في وقت حدوث التوزيع.

ملاحظة: تكتب TypeScript فعليًا الأنواع الحرفية للقوالب النصية باستخدام سلاسل محاطة بعلامات backtick وتحتوي على مواضع ${}. نعرض هذا النمط في هذه المقاطع بصيغة Tpl<...>، مع سرد كل جزء بالترتيب؛ فمثلًا يظهر قالب backtick الذي يطابق البادئة الحرفية ثم 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: الحساب في نظام الأنواع.

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

هل درس «الأنواع الشرطية التوزيعية» مجاني؟

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

ماذا ستتعلم في «الأنواع الشرطية التوزيعية»؟

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

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

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

كم من الوقت يستغرق درس «الأنواع الشرطية التوزيعية»؟

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

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

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

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

  1. الأنواع كلغة للحساب
  2. الشروط على مستوى النوع
  3. التكرار على مستوى النوع
  4. الأنواع الشرطية التوزيعية
← العودة إلى TypeScript Academy