0Pricing
TypeScript Academy · درس

بناء الاتحادات المميّزة

وسموا أعضاء الاتحاد بخاصية مميّزة مشتركة

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

ما الاتحاد المميّز؟

الاتحاد المميّز هو اتحاد من أنواع الكائنات تشترك جميعها في خاصية literal شائعة تُسمى الخاصية المميّزة. وتتيح هذه العلامة المشتركة لـ TypeScript التمييز بين الأعضاء.

// The shared "kind" property is the discriminant
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;

الخاصية المميّزة

يجب أن تكون الخاصية المميّزة نوعًا حرفيًا مثل "circle"، لا نوعًا واسعًا مثل string. ويحصل كل عضو على قيمة حرفية فريدة خاصة به.

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };

const c: Circle = { kind: "circle", radius: 10 };
console.log(c.kind); // "circle"

لكل عضو حقوله الخاصة

إلى جانب الخاصية المميّزة المشتركة، يحمل كل عضو الحقول التي لا معنى لها إلا بالنسبة إليه. فالدائرة لها radius، والمربع له side.

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Rectangle = { kind: "rectangle"; width: number; height: number };
type Shape = Circle | Square | Rectangle;

إنشاء قيم الاتحاد

عند إنشاء قيمة، يتحقق TypeScript من أن بنيتها تطابق عضوًا واحدًا بالضبط من أعضاء الاتحاد، استنادًا إلى kind.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const shapes: Shape[] = [
  { kind: "circle", radius: 5 },
  { kind: "square", side: 4 }
];
console.log(shapes.length); // 2

لماذا لا نستخدم الحقول الاختيارية فقط؟

يسمح النوع الفضفاض ذو الحقول الاختيارية (radius? وside?) بتركيبات غير صالحة. أما الاتحاد المميّز فيجعل الحالات غير القانونية غير قابلة للتمثيل.

// Loose and error-prone: nothing stops radius + side together
type BadShape = { radius?: number; side?: number };
const bad: BadShape = { radius: 5, side: 4 }; // nonsense, but allowed

اسم الخاصية المميّزة متروك لك

تُسمى العلامة عادةً kind أو type، لكن يمكن استخدام أي اسم، ما دام كل عضو يستخدم اسم الخاصية نفسه مع قيمة حرفية مميّزة.

type Event =
  | { type: "click"; x: number; y: number }
  | { type: "scroll"; delta: number };

const e: Event = { type: "click", x: 10, y: 20 };
console.log(e.type); // "click"

نمذجة حاسبة مساحة الأشكال

تتألق الاتحادات المميّزة عندما يحتاج كل نوع مختلف إلى معالجة مختلفة. سنُعدّ هنا أشكالًا ستعالجها لاحقًا دالة حساب المساحة.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const myShapes: Shape[] = [
  { kind: "circle", radius: 3 },
  { kind: "square", side: 6 }
];
console.log("Count:", myShapes.length);

إضافة نوع مختلف ثالث

الاتحادات قابلة للتوسعة. فإضافة عضو triangle لا تتطلب سوى تغيير من سطر واحد، وسيتتبعه TypeScript في كل موضع يُستخدم فيه الاتحاد.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number; height: number };

const t: Shape = { kind: "triangle", base: 4, height: 8 };
console.log(t.kind);

القيم الحرفية الفريدة تمنع التداخل

بما أن كل قيمة kind فريدة، فلا يوجد أي التباس. إذ تنتمي القيمة إلى عضو واحد بالضبط، ولا يمكن أن تنتمي إلى عضوين في الوقت نفسه.

type A = { kind: "a"; value: number };
type B = { kind: "b"; label: string };
type Union = A | B;

function describe(u: Union) {
  return u.kind === "a" ? u.value : u.label;
}
console.log(describe({ kind: "b", label: "hi" }));

الخصائص المميّزة ذات العلامات المنطقية

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

type Result =
  | { ok: true; data: string }
  | { ok: false; error: string };

const r: Result = { ok: true, data: "loaded" };
console.log(r.ok ? r.data : r.error);

الاتحادات المميّزة عمليًا

أصبح لديك الآن نموذج مكتمل للأشكال. في الدرس التالي سنجري تضييقًا استنادًا إلى الخاصية المميّزة للوصول بأمان إلى الحقل الخاص بكل عضو.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const sample: Shape = { kind: "circle", radius: 7 };
console.log(sample.kind, "ready");

تحقق سريع: الخصائص المميّزة

اختبر فهمك للاتحادات المميّزة.

مراجعة: إنشاء الاتحادات المميّزة

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

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const done: Shape = { kind: "square", side: 2 };
console.log("Recap complete:", done.kind);

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

هل درس «بناء الاتحادات المميّزة» مجاني؟

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

ماذا ستتعلم في «بناء الاتحادات المميّزة»؟

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

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

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

كم من الوقت يستغرق درس «بناء الاتحادات المميّزة»؟

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

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

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

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

  1. بناء الاتحادات المميّزة
  2. تضييق النوع اعتمادًا على المميّز
  3. التحقق من اكتمال الحالات باستخدام never
  4. نمذجة آلات الحالات
← العودة إلى TypeScript Academy