الثوابت في TypeScript: كيفية تعريفها واستخدامها في الفئات

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الثوابت في فئات TypeScript: من المبتدئ إلى المحترف

\n\n

هل سبق لك أن كتبت كودًا بلغة TypeScript وأدركت فجأة: «هذه السلسلة النصية السحرية "ADMIN" أستخدمها في عشرة أماكن، وإذا أخطأت في كتابتها - سيبقى المترجم صامتًا»؟ ألم مألوف. أو الأسوأ من ذلك، أن يقوم أحد أعضاء الفريق بتغيير قيمة الثابت مباشرة في وقت التشغيل، وتقضي ساعة في التصحيح لتفهم لماذا تعطل كل شيء.

\n\n

مرحبًا بك في عالم ثوابت الفئات في TypeScript. هذا ليس مجرد سكر نحوي - بل هو أساس لبنية نظيفة وقابلة للتنبؤ وآمنة. في هذه المقالة، سنستعرض جميع طرق تعريف الثوابت في فئات TypeScript: من readonly البسيط إلى التقنيات المتقدمة مع as const والأجناس (Generics). هيا بنا!

\n\n

لماذا الثوابت في الفئات مهمة؟

\n\n

تخيل أنك تطور تطبيقًا لمتجر إلكتروني. لديك فئة Order، وفيها حالات: "pending"، "shipped"، "delivered". إذا قمت بتوزيع هذه السلاسل النصية في جميع أنحاء الكود، عاجلاً أم آجلاً سيكتب أحدهم "PENDING" بحرف كبير - وسيحدث الخطأ. ثوابت الفئات في TypeScript تحل هذه المشكلة مرة واحدة وإلى الأبد.

\n\n
    \n
  • أمان الأنواع: لن يسمح المترجم بتمرير "pendingg" حيثما يكون "pending" مطلوبًا.
  • \n
  • قابلية القراءة: OrderStatus.Pending أوضح من مجرد سلسلة نصية.
  • \n
  • سهولة الصيانة: تغيير القيمة في مكان واحد يغيرها في كل مكان.
  • \n
\n\n

الطريقة رقم 1: readonly - الأساس ولكن مع تفاصيل

\n\n

أبسط طريقة هي استخدام المُعدِّل readonly. فهو يمنع تغيير الحقل بعد التهيئة.

\n\n
class AppConfig {\n    readonly API_URL: string = 'https://api.example.com';\n    readonly MAX_RETRIES: number = 3;\n}\n\nconst config = new AppConfig();\nconsole.log(config.API_URL); // 'https://api.example.com'\n// config.API_URL = 'new-url'; // خطأ! لا يمكن التعيين لـ 'API_URL' لأنه خاصية للقراءة فقط.
\n\n

لكن هناك خدعة: readonly يعمل فقط على مستوى TypeScript. في JavaScript المُجمَّع، لا يزال من الممكن تغيير هذه الحقول. للحماية الكاملة، استخدم Object.freeze أو # (الحقول الخاصة).

\n\n

الطريقة رقم 2: static readonly - ملك الثوابت

\n\n

إذا كان الثابت غير مرتبط بمثيل معين من الفئة (وهذا يحدث في 99% من الحالات)، استخدم static readonly. هذا هو النمط الكلاسيكي class constant typescript.

\n\n
class MathConstants {\n    static readonly PI: number = 3.14159;\n    static readonly E: number = 2.71828;\n    static readonly GOLDEN_RATIO: number = 1.61803;\n}\n\n// الوصول دون إنشاء مثيل\nconsole.log(MathConstants.PI); // 3.14159\n// MathConstants.PI = 3.14; // خطأ!
\n\n

هذا النهج مثالي للإعدادات، والثوابت الرياضية، والحالات، وأي قيم لا ينبغي أن تتغير.

\n\n

الطريقة رقم 3: enum - عندما تكون الثوابت كثيرة

\n\n

إذا كان لديك مجموعة من الثوابت المرتبطة (مثل حالات الطلب)، فإن enum هو أفضل صديق لك. فهو ينشئ مجموعة مسماة من القيم.

\n\n
enum OrderStatus {\n    Pending = 'pending',\n    Shipped = 'shipped',\n    Delivered = 'delivered',\n    Cancelled = 'cancelled'\n}\n\nclass Order {\n    constructor(public status: OrderStatus) {}\n}\n\nconst order = new Order(OrderStatus.Pending);\nconsole.log(order.status); // 'pending'\n\n// order.status = 'pendingg'; // خطأ! النوع '"pendingg"' غير قابل للإسناد للنوع 'OrderStatus'
\n\n

نصيحة: إذا كنت تستخدم enum نصيًا (كما في المثال)، فإنه يعطي قيمًا قابلة للقراءة في وقت التشغيل. enum الرقمية أسرع، ولكن يصعب تصحيح أخطائها.

\n\n

الطريقة رقم 4: as const - لأقصى درجات الصرامة

\n\n

أحيانًا تريد أن يصبح الكائن أو المصفوفة ثا

المدونات

توصيات الكتب