المقدمة: لماذا نحتاج إلى مراجعة الكود (code review) في TypeScript؟
مراجعة الكود (code review) ليست مجرد فحص شكلي للكود قبل الدمج (merge). بل هي أداة قوية لتحسين جودة المشروع، وتبادل المعرفة داخل الفريق، ومنع الأخطاء (bugs) في المراحل المبكرة. عندما يتعلق الأمر بـ TypeScript، تكتسب مراجعة الكود أهمية خاصة: فالكتابة الثابتة (static typing)، ونظام الأدوية (generics) القوي، وإعدادات المترجم (compiler) الصارمة تسمح باكتشاف العديد من الأخطاء حتى قبل تشغيل التطبيق. ومع ذلك، حتى في TypeScript توجد مطبات (pitfalls) يسهل التغاضي عنها.
في هذه المقالة، سنناقش ما يجب الانتباه إليه عند مراجعة كود TypeScript، وكيفية تقديم ملاحظات (feedback) تكون مفيدة وليست مسيئة.
1. الكتابة (Typing) والأدوية (Generics): لا تدع any يفسد كل شيء
أحد الأهداف الرئيسية لـ TypeScript هو جعل الأنواع (types) صريحة. إذا ظهر any في الكود، فهذه دائمًا علامة حمراء. أثناء مراجعة الكود، تحقق من:
- غياب
any. استبدله بـunknownمع التحقق من النوع لاحقًا، أو بنوع محدد. - صحة الأدوية (generics). تأكد من أن معاملات الأنواع (type parameters) لا تُفقد ولا تصبح واسعة جدًا. على سبيل المثال:
// سيء: نفقد النوعfunction getFirst(arr: any[]): any { return arr[0];}
// جيد: نحافظ على النوع عبر الدواء (generic)function getFirst<T>(arr: T[]): T | undefined { return arr[0];}- كتابة استجابات API. إذا جاء JSON من الخادم، يجب وصفه بواسطة واجهة (interface)، وليس
any. - أنواع الأدوات (Utility types). استخدم
Partial،Pick،Omitللعمل بمرونة مع الكائنات — فهذا يقلل من تكرار الكود.
نصيحة: قم بتفعيل العلم strict: true و noImplicitAny: true في ملف tsconfig.json — فهذا سيمنع معظم المشاكل على مستوى التجميع (compilation).
2. المنطق ومعالجة الأخطاء: لا تصمت عن المشاكل
TypeScript لا يحمي من الأخطاء المنطقية، لذلك يجب أن تتحقق مراجعة الكود من منطق الأعمال (business logic) ومعالجة الاستثناءات (exception handling).
ما الذي يجب النظر إليه:
- معالجة الحالات الحدودية (edge cases). ماذا سيحدث إذا كانت المصفوفة فارغة، أو الكائن
null، أو السلسلة النصية فارغة؟ مثال:
// سيء: لا نتحقق من وجود العنصرfunction getUserName(users: User[], id: string): string { return users.find(u => u.id === id)!.name; // قد يتسبب في خطأ}
// جيد: نتحققfunction getUserName(users: User[], id: string): string | null { const user = users.find(u => u.id === id); return user ? user.name : null;}- العمليات غير المتزامنة (asynchronous operations). تأكد من معالجة الـ promises بشكل صحيح عبر
async/await، وأن الأخطاء يتم التقاطها فيtry/catch. - تجنب التحويرات (mutations). إذا كانت الدالة لا يجب أن تغير البيانات المدخلة، استخدم
readonlyوالطرق غير القابلة للتغيير (immutable methods) (مثلmapبدلاً منforEachمع تغيير مصفوفة خارجية).
3. أسلوب الكود وسهولة القراءة: الكود يُكتب للبشر
حتى الكود المكتوب بأنواع مثالية قد يكون غير قابل للقراءة. مراجعة الكود هي فرصة ممتازة لمناقشة الأسلوب.
النقاط الرئيسية:
- التسمية (naming). يجب أن تعبر المتغيرات والدوال والكلاسات عن غرضها. تجنب الأسماء المكونة من حرف واحد (باستثناء عدّادات الحلقات). مثال:
fetchUserDataأفضل منgetData. - حجم الدوال. يجب ألا تقوم الدالة بأكثر من شيء واحد. إذا كان طولها يتجاوز 20-30 سطرًا، فهذا سبب للتفكير في إعادة الهيكلة (refactoring).
- التعليقات (comments). يجب أن تشرح التعليقات لماذا كُتب الكود بهذه الطريقة، وليس ماذا يفعل. إذا كان التعليق يكرر الكود — قم بإزالته.
- التنسيق (formatting). استخدم