لماذا التحقق من قيمة في Enum TypeScript؟ مثال عملي حي
\n\nتخيل: أنت تكتب خادمًا خلفيًا (باك إند) على Node.js مع TypeScript. يرسل العميل حالة الطلب - سلسلة نصية "shipped". لديك enum OrderStatus مع الخيارات: Pending, Processing, Shipped, Delivered. ولكن فجأة تصل "CANCELLED" أو "unknown". ماذا تفعل؟ صحيح - تحقق مما إذا كانت القيمة موجودة في enum TypeScript.
هذه المهمة هي واحدة من أكثر المهام شيوعًا على Stack Overflow (آلاف المشاهدات). وليس من دون سبب: enum في TypeScript ليس مجرد مجموعة من الثوابت، بل هو وحش ماكر بأنواع رقمية ونصية. في هذا الدليل، سنقوم بتحليل جميع طرق التحقق من وجود قيمة في enum، من البسيطة إلى المتقدمة، مع أمثلة كود وشروحات.
\n\nإذا كنت قد بدأت للتو في تعلم TypeScript أو ترغب في تعميق معرفتك - فهذه المقالة لك. هيا بنا!
\n\nما هو Enum في TypeScript؟ نبذة مختصرة
\n\nEnum (تعداد) هو طريقة لتعيين مجموعة من الثوابت المسماة. في TypeScript، هناك نوعان من enum:
\n\n- \n
- Enum رقمية - يتم زيادة القيم تلقائيًا (0, 1, 2...). \n
- Enum نصية - يتم تعيين سلسلة نصية صراحة لكل عضو. \n
مثال على enum رقمية:
\n\nenum Direction {\n Up, // 0\n Down, // 1\n Left, // 2\n Right // 3\n}\n\nمثال على enum نصية:
\n\nenum Status {\n Active = "ACTIVE",\n Inactive = "INACTIVE",\n Pending = "PENDING"\n}\n\nلماذا التحقق من القيمة على الإطلاق؟ لأن البيانات من الخارج (API، نماذج، قواعد بيانات) يمكن أن تكون أي شيء. بدون التحقق، فإنك تخاطر بالحصول على undefined أو خطأ في وقت التشغيل.
الطريقة 1. الكلاسيكية: Object.values() + includes()
\n\nالطريقة الأكثر شيوعًا وقابلية للقراءة هي تحويل enum إلى مصفوفة من القيم والتحقق من الاحتواء باستخدام includes().
لـ enum النصية:
\n\nenum Color {\n Red = "RED",\n Green = "GREEN",\n Blue = "BLUE"\n}\n\nfunction isColor(value: string): boolean {\n return Object.values(Color).includes(value as Color);\n}\n\nconsole.log(isColor("RED")); // true\nconsole.log(isColor("YELLOW")); // false\n\nلـ enum الرقمية - خدعة! Object.values() يُرجع تخطيطًا عكسيًا (مفاتيح وقيم). لذلك تحتاج إلى تصفية الأرقام فقط:
enum NumberEnum {\n A = 1,\n B = 2,\n C = 3\n}\n\nfunction isNumberEnumValue(value: number): boolean {\n return Object.values(NumberEnum).filter(v => typeof v === 'number').includes(value);\n}\n\nconsole.log(isNumberEnumValue(2)); // true\nconsole.log(isNumberEnumValue(5)); // false\n\nهذا الأسلوب عالمي، لكنه يتطلب الحذر مع enum الرقمية. الميزة: بسيط وواضح. العيب: يجب تذكر التصفية.
\n\nالطريقة 2. Type Guard: التحقق عبر مفاتيح enum
\n\nإذا كنت لا تحتاج فقط إلى التحقق من القيمة، بل أيضًا إلى الحصول على ضمان النوع، استخدم type guard. هذه الطريقة مفيدة بشكل خاص عند العمل مع API، حيث تريد تضييق النوع.
\n\nenum UserRole {\n Admin = "admin",\n User = "user",\n Guest = "guest"\n}\n\nfunction isUserRole(value: string): value is UserRole {\n return Object.values(UserRole).includes(value as UserRole);\n}\n\nfunction processRole(role: string) {\n if (isUserRole(role)) {\n // TypeScript يعرف أن role هو UserRole\n console.log(`الدور: ${role}`);\n } else {\n console.log("دور غير معروف");\n }\n}\n\nprocessRole("admin"); // الدور: admin\nprocessRole("moderator"); // دور غير معروف\n\nهذا الأسلوب يوفر أمان الأنواع ويقلل عدد التحققات في الكود. أوصي به للمشاريع الجادة.
\n\n