كيفية تحويل سلسلة نصية إلى enum في TypeScript: دليل خطوة بخطوة
\n\nهل سبق لك أن واجهت موقفًا حيث يعيد API سلسلة نصية، بينما نموذج TypeScript الخاص بك مصمم بشكل صارم باستخدام enum؟ أو ربما تحصل على قيمة من localStorage وتريد تحويلها بأمان إلى تعداد؟ إذا كان الأمر كذلك، فأنت في المكان الصحيح. في هذه المقالة، سنشرح كيفية تحويل سلسلة نصية إلى enum في TypeScript — بدءًا من الحلول البسيطة وصولاً إلى التقنيات المتقدمة مع معالجة الأخطاء.
هذا الموضوع هو من أكثر المواضيع شيوعًا على Stack Overflow (آلاف المشاهدات!)، وليس من دون سبب. حتى المطورين ذوي الخبرة غالبًا ما يختلط عليهم الأمر عندما يتعلق الأمر بتحويل السلاسل النصية إلى تعدادات بأمان. دعنا نوضح الأمور بالتفصيل.
\n\nما هو enum في TypeScript ولماذا نحتاج إلى تحويله؟
\n\nEnum (التعداد) هو أداة قوية في TypeScript تتيح لك تحديد مجموعة من الثوابت المسماة. بدلاً من استخدام "سلاسل نصية سحرية" مثل 'active' أو 'pending'، يمكنك تعريف enum والعمل بقيم مصنفة. لكن المشكلة تكمن في أن البيانات من المصادر الخارجية (API، نماذج، ملفات إعدادات) غالبًا ما تأتي كسلاسل نصية عادية. وهنا يطرح السؤال: كيفية تحويل سلسلة نصية إلى enum في TypeScript بأمان وبأناقة؟
// مثال على enum\nenum Status {\n Active = 'active',\n Inactive = 'inactive',\n Pending = 'pending'\n}\n\n// سلسلة نصية من API\nconst apiStatus: string = 'active';\n// كيف نحصل على Status.Active؟ 🤔\n\nالطريقة 1: التحويل المباشر للنوع (Type Assertion)
\n\nالطريقة الأسهل، ولكنها أيضًا الأكثر خطورة. أنت ببساطة تقول لـ TypeScript: "ثق بي، هذه هي القيمة الصحيحة".
\n\nconst status = apiStatus as Status;\n// أو\nconst status = <Status>apiStatus;\n\nالميزة: أقل كود ممكن. العيب: إذا كانت السلسلة النصية لا تتطابق مع أي قيمة من enum، فستحصل على undefined دون أي تحذير. لن يرمي TypeScript خطأً، وستكتشف المشكلة فقط في وقت التشغيل (runtime) عندما يحدث عطل ما.
يجب استخدام هذه الطريقة فقط إذا كنت متأكدًا تمامًا من مصدر البيانات. للإنتاج (production) — غير موصى بها.
\n\nالطريقة 2: استخدام دالة مساعدة مخصصة
\n\nهذه هي المنطقة الوسطى بين البساطة والأمان. سنكتب دالة تأخذ سلسلة نصية وتتحقق مما إذا كانت هذه القيمة موجودة في enum.
\n\nfunction stringToEnum<T>(value: string, enumObject: T): T[keyof T] | undefined {\n // نتحقق مما إذا كانت القيمة موجودة في enum\n const enumValues = Object.values(enumObject) as string[];\n if (enumValues.includes(value)) {\n return value as unknown as T[keyof T];\n }\n return undefined;\n}\n\n// الاستخدام\nconst status = stringToEnum(apiStatus, Status);\nif (status) {\n console.log(status); // Status.Active\n} else {\n console.error('قيمة حالة غير صحيحة');\n}\n\nهذه الدالة تحول السلسلة النصية إلى enum في TypeScript بأمان. إذا لم يتم العثور على القيمة، فإنها تعيد undefined، ويمكنك معالجة هذه الحالة. لاحظ استخدام النوع العام <T> — فهو يجعل الدالة عامة لأي enum.
الطريقة 3: نهج صارم مع رمي خطأ
\n\nأحيانًا، undefined ليس ما تحتاجه. من الأفضل رمي خطأ بشكل صريح لاكتشاف المشكلة بسرعة.
function stringToEnumStrict<T>(value: string, enumObject: T): T[keyof T] {\n const enumValues = Object.values(enumObject) as string[];\n if (enumValues.includes(value)) {\n return value as unknown as T[keyof T];\n }\n throw new Error(`القيمة "${value}" غير موجودة في enum`);\n}\n\n// الاستخدام\ntry {\n const status = stringToEnumStrict(apiStatus, Status);\n // نعمل مع status\n} catch (error) {\n console.error(error.message);\n // نسجل الخطأ في Sentry أو أي نظام مراقبة آخر\n}