مقدمة: لماذا "مجرد الترجمة" هو معيار سيء
\nتخيل موقفًا: تفتح طلب سحب على GitHub، ترى علامة CI الخضراء وتسمع صوتًا داخليًا: "الأنواع متطابقة - إذن الكود صحيح". مألوف؟ إذا كان الأمر كذلك، فأنت تقع في فخ نسميه "الشعور الزائف بالأمان في TypeScript".
\nTypeScript ليس حلاً سحريًا. فهو لا يكتشف الأخطاء المنطقية، ولا يتحقق من متطلبات العمل، وبالتأكيد لا يضمن أن كودك لن ينهار في وقت التشغيل. لهذا السبب، مراجعة الكود في TypeScript ليست مجرد "إلقاء نظرة سريعة"، بل هي منهج منظم. في هذه المقالة، سأخبرك بما يجب أن تنظر إليه حقًا عند مراجعة كود TypeScript. أدوّن على PythonLib، وهنا اعتدنا على التعمق - استعد.
\n\n1. النوع any: العلم الأحمر
\nالأكثر وضوحًا، لكنه للأسف الأكثر شيوعًا. any هو مفتاح إيقاف TypeScript. إذا رأيت any في الكود، مهمتك هي فهم: هل هو كسل من المؤلف أم حالة مبررة حقًا؟
مثال سيء:
\nfunction processData(data: any) {\n return data.name.toLowerCase();\n}\nهنا نفقد كل المعلومات عن النوع. إذا وصل data بقيمة null أو undefined - مرحبًا بك في خطأ وقت التشغيل.
مثال جيد:
\ninterface UserData {\n name: string;\n age?: number;\n}\n\nfunction processData(data: UserData) {\n return data.name.toLowerCase();\n}\nما يجب التحقق منه في مراجعة الكود: إذا كان any لا يزال مستخدمًا (على سبيل المثال، للعمل مع JSON بهيكل غير معروف)، هل يطلب المؤلف التحقق من الصحة عند الإدخال؟ غالبًا ما يخفي any عدم وجود كتابة صحيحة للبيانات الخارجية.
2. الوضع الصارم: لا تقم بتعطيله
\nأول شيء أتحقق منه في tsconfig.json هو العلامة strict: true. إذا لم تكن موجودة، فأنت تحرم نفسك من طبقة كاملة من الفحوصات: strictNullChecks، noImplicitAny، strictFunctionTypes وغيرها.
بدون strictNullChecks يمكنك كتابة:
const user = getUser(); // قد يعيد null\nconst name = user.name; // TS لن يشتكي، لكنه سينهار في وقت التشغيل\nفي مراجعة الكود: إذا رأيت أن المشروع يعمل بدون الوضع الصارم - اقرع ناقوس الخطر. هذا دين تقني يتراكم بشكل هائل. من الأفضل قضاء يوم في تفعيل الوضع الصارم وإصلاح الأخطاء بدلاً من قضاء شهر في مطاردة الأخطاء في الإنتاج.
\n\n3. الأدوية العامة: القوة والمسؤولية
\nالأدوية العامة هي القوة الخارقة لـ TypeScript. لكن مع القوة العظيمة تأتي مسؤولية كبيرة. في مراجعة الكود، أنظر دائمًا: هل بالغ المؤلف في تعقيد الأنواع؟
\nمثال على التعقيد المفرط:
\nfunction identity<T extends Record<string, unknown>>(arg: T): T {\n return arg;\n}\nلماذا تقييد T بـ Record<string, unknown> إذا كنا ببساطة نعيد نفس الشيء؟ يكفي:
function identity<T>(arg: T): T {\n return arg;\n}\nما يجب التحقق منه:
\n- \n
- هل تُستخدم الأدوية العامة حيث تكون المرونة مطلوبة، أم يمكن الاكتفاء بنوع محدد؟ \n
- هل هناك قيود زائدة (extends) تعيق إعادة الاستخدام؟ \n
- هل تم استنتاج الأنواع بشكل صحيح - ألا يضطر المستخدم إلى تحديد
<SomeType>يدويًا حيث كان بإمكان TS تخمينها بنفسه؟ \n
4. unknown vs any: اختر السلاح الصحيح
\nعند العمل مع بيانات نوعها غير معروف لك (API، localStorage، إدخال المستخدم)، استخدم unknown بدلاً من any. unknown يجبرك على التحقق صراحة من النوع قبل الاستخدام.
سيء:
\n<