التأمل والاستبطان في TypeScript: كيف ينظر الكود إلى نفسه

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

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

ابدأ الدورة

التأمل والاستبطان في TypeScript: كيف ينظر الكود إلى نفسه

\n\n

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

\n\n

في هذه المقالة، سنوضح الفرق بين التأمل والاستبطان، وكيفية استخدامهما في TypeScript، ولماذا قد يكون ذلك مفيدًا في المشاريع الحقيقية. لا نظرية مملة — فقط كود حي وأمثلة عملية.

\n\n

ما هو الاستبطان والتأمل؟

\n\n

دعنا نوضح الأمور فورًا. في البرمجة، غالبًا ما يتم الخلط بين هذين المصطلحين، لكن هناك فرق:

\n\n
    \n
  • الاستبطان — هو قدرة البرنامج على مراقبة هيكله. يمكنك معرفة الخصائص التي يمتلكها الكائن، وما هو نوعه، لكن لا يمكنك تغييرها.
  • \n
  • التأمل — هو مستوى أكثر تقدمًا: لا ينظر البرنامج إلى نفسه فحسب، بل يغير سلوكه في وقت التشغيل. على سبيل المثال، استدعاء الأساليب ديناميكيًا أو إنشاء مثيلات جديدة للفئات.
  • \n
\n\n

في JavaScript، التي يعتمد عليها TypeScript، يتم تنفيذ التأمل من خلال Reflect وProxy. لكن TypeScript يضيف طبقة خاصة به — الكتابة الثابتة، التي تختفي جزئيًا أثناء التجميع. وهنا يبدأ الجزء المثير للاهتمام.

\n\n

استبطان الأنواع: حواجز الأنواع و typeof

\n\n

أبسط طريقة للنظر داخل الكود هي استخدام حواجز الأنواع. وهي تركيبات تتحقق من نوع البيانات في وقت التشغيل:

\n\n
function isString(value: unknown): value is string {\n  return typeof value === 'string';\n}\n\nfunction processValue(value: unknown) {\n  if (isString(value)) {\n    // TypeScript يعلم أن value هي سلسلة نصية\n    console.log(value.toUpperCase());\n  } else {\n    console.log('هذا ليس سلسلة نصية');\n  }\n}
\n\n

لاحظ value is string — هذا هو مسند النوع. يخبر TypeScript أنه بعد التحقق، المتغير ينتمي إلى نوع معين. هذا استبطان خالص: نحن ننظر إلى النوع، لكننا لا نغيره.

\n\n

التأمل من خلال واجهة Reflect API

\n\n

كائن Reflect هو آلية تأمل مدمجة في JavaScript. يسمح بتنفيذ إجراءات كانت تتم سابقًا بطرق "سحرية"، لكنها الآن موحدة. إليك بعض الأمثلة:

\n\n
const user = {\n  name: 'أليكسي',\n  age: 30,\n};\n\n// استبطان — الحصول على قائمة المفاتيح\nconsole.log(Reflect.ownKeys(user)); // ['name', 'age']\n\n// تأمل — قراءة خاصية ديناميكيًا\nconst propertyName = 'name';\nconsole.log(Reflect.get(user, propertyName)); // 'أليكسي'\n\n// تأمل — تعيين خاصية ديناميكيًا\nReflect.set(user, 'name', 'ماريا');\nconsole.log(user.name); // 'ماريا'
\n\n

لماذا Reflect أفضل من الطريقة القديمة user[prop]؟ أولاً، يعيد boolean لعمليات التعيين، مما يسهل التحقق. ثانيًا، يعمل بشكل صحيح مع الـ Proxy وواصفات الخصائص. بالنسبة لـ TypeScript، هذا مهم بشكل خاص، لأن التأمل يسمح بتجاوز الكتابة الثابتة عندما يكون ذلك ضروريًا حقًا.

\n\n

المزينات: تأمل معزز

\n\n

المزينات هي، بلا شك، المثال الأبرز على التأمل في TypeScript. تسمح بتعليق الفئات والطرق والخصائص والمعاملات، ثم تغيير سلوكها. منذ إصدار TypeScript 5.0، أصبحت المزينات قياسية (المرحلة 3).

\n\n

إليك كيف يبدو مزين بسيط لتسجيل استدعاء طريقة:

\n\n
function logMethod(\n  target: any,\n  propertyKey: string,\n  descriptor: PropertyDescriptor\n) {\n  const originalMethod = descriptor.valu                

المدونات

توصيات الكتب