kind الأنواع الاتحادية القابلة للتمييز
آخر تحديث: 2026-10-22
kind الأنواع الاتحادية القابلة للتمييز
يربط النوع الاتحادي القابل للتمييز (ويُسمى أيضًا tagged union) مجموعة أنواع بحقل تمييز مشترك (مثل status أو kind) تأخذ قيمته قيمةً حرفية مختلفة لكل عضو. وعند التبديل على حقل التمييز عبر switch يضيّق TS النوع تلقائيًا إلى العضو المطابق — وهو أكثر أنماط الأنواع الاتحادية عملية في نمذجة الأعمال.
| المجموعة | تضييق الأنواع والتأكيدات |
|---|---|
| النوع | نوع |
| الوضع الصارم | غير مطلوب |
ℹ️ معلومة يحوّل المحرر لغة TypeScript إلى JavaScript ثم يشغّلها (بدون فحص أنواع)؛ راجع ناتج كل مثال لنتيجة فحص الأنواع.
📝 الصيغة
type Result<T> =
| { status: "loading" }
| { status: "success"; data: T }
| { status: "error"; message: string };
function handle<T>(res: Result<T>) {
switch (res.status) {
case "loading": /* res: بلا data */ break;
case "success": res.data; break; // مضيَّق إلى العضو success
case "error": res.message; break;
}
}
⚙️ المعاملات
| discriminant | حقل التمييز: يجب أن يعلنه كل عضو، بقيمة حرفية (نوع literal) مختلفة لكل عضو (مثل "loading" / "success" / "error") |
|---|
القيمة المُعادة:لا قيمة معادة — النوع الاتحادي القابل للتمييز وسيلة نمذجة على مستوى الأنواع؛ ويُستثار التضييق بمقارنة switch/if على حقل التمييز ويتم في وقت الترجمة.
▶ مثال
عدّل الكود أدناه واضغط «جرّب» لرؤية نتيجة التحويل:
الناتج:
loading…
got 3 items
error: timeout
(مخرجات التشغيل بعد الترجمة؛ نجاح الفحص النوعي للوصول إلى res.data في فرع success سببه التضييق بحقل التمييز — مضمون ساكنًا بواسطة tsc، وفي وقت التشغيل لا توجد سوى القيم)
💡 نقاط مهمة
ℹ️ معلومة لا قيود على تسمية حقل التمييز — type وkind وstatus وstate وtag كلها شائعة؛ المهم أن يأخذ كل عضو قيمة حرفية مختلفة حتى يتمكن TS من تمييزه منفردًا.
⚠️ تنبيه يجب أن يكون حقل التمييز حقلًا واجبًا من نوع حرفي. فإذا كُتب string (بدلًا من حرفية مثل "success") أو عُلّم اختياريًا زالت قوته التمييزية وتوقف التضييق عن العمل.
💡 تلميح النوع الاتحادي القابل للتمييز وفحص الاستنفاد شريكان ذهبيان: بعد التبديل على جميع قيم التمييز، سيشير المترجم إلى كل فرع منسي عند إضافة عضو جديد (استخدم معه assertNever — انظر مدخلة exhaustive-checks).
🏷️ تضييق الأنواع والتأكيدات ذو صلة
💡 حالات ذات صلة
المزيد من الحالات قادم قريبًا.
📚 دروس ذات صلة
❓ أسئلة شائعة
س ما الفرق بين النوع الاتحادي القابل للتمييز والاتحاد العادي؟
ج الاتحاد العادي لا يضيّق إلا عبر فحوصات عامة مثل typeof/in؛ أما القابل للتمييز فيضيف حقل تمييز حرفي بحيث ينقلك switch واحد على حقل واحد إلى عضو بعينه بدقة، ويتيح أيضًا فحص الاستنفاد. صمّم حقل تمييز متى استطعت.
س هل يمكن أن يكون حقل التمييز متداخلًا داخل كائن؟
ج نعم، يدعم TS التضييق على حقول تمييز متداخلة (بل وعناصر مصفوفات) مثل res.meta.state. لكن التداخل العميق يقلل القراءة، والعُرف هو وضع حقل التمييز في المستوى الأعلى.
س هل يصح استخدام enum رقمي كقيمة تمييز؟
ج نعم. أعضاء الـ enum (الرقمية منهم) أنواع حرفية، فاختلاف قيم الـ enum بين الأعضاء يشكّل نوعًا اتحاديًا قابلًا للتمييز؛ وقراءة string enum عند التصحيح أوضح من الرقمية.