معالجة الأخطاء في TypeScript: من try/catch إلى كود موثوق
يضيف TypeScript الكتابة الثابتة إلى JavaScript، لكن أخطاء وقت التشغيل تظل جزءًا لا يتجزأ من التطوير. يمكن أن تؤدي المعالجة غير الصحيحة للاستثناءات إلى تعطل التطبيق، أو تسرب البيانات، أو عمل غير صحيح لواجهة المستخدم. في هذه المقالة، سنشرح كيفية معالجة الأخطاء في TypeScript بكفاءة باستخدام الآليات المدمجة والأنماط المتقدمة.
try/catch الأساسي في TypeScript
تركيبة try/catch هي أساس معالجة الأخطاء. في TypeScript، على عكس JavaScript، يمكننا تحديد نوع الخطأ الملتقط. ومع ذلك، هناك فارق مهم: افتراضيًا، نوع الخطأ في كتلة catch هو unknown، وليس Error.
try { const data = JSON.parse('json غير صالح'); console.log(data);} catch (error) { // error له نوع unknown if (error instanceof Error) { console.error('حدث خطأ:', error.message); } else { console.error('خطأ غير معروف:', error); }}لماذا هذا مهم؟ في JavaScript، يمكنك رمي أي شيء: سلسلة نصية، رقم، كائن. TypeScript يحمينا من الوصول غير الآمن لخصائص الخطأ دون تحقق. يُوصى دائمًا بالتحقق من نوع الخطأ قبل الاستخدام.
فئات الأخطاء المخصصة
لمعالجة أكثر دقة، قم بإنشاء فئات الأخطاء الخاصة بك التي توسع Error المدمج. هذا يسمح بالتمييز بين أنواع الأخطاء ونقل معلومات إضافية.
class ValidationError extends Error { constructor( public field: string, message: string ) { super(message); this.name = 'ValidationError'; }}
class NetworkError extends Error { constructor( public statusCode: number, message: string ) { super(message); this.name = 'NetworkError'; }}
function processUserData(data: unknown): void { if (!data || typeof data !== 'object') { throw new ValidationError('data', 'بيانات غير صحيحة'); } if (!('email' in data)) { throw new ValidationError('email', 'البريد الإلكتروني إلزامي'); }}
try { processUserData({ name: 'إيفان' });} catch (error) { if (error instanceof ValidationError) { console.error(`خطأ في التحقق من الحقل ${error.field}: ${error.message}`); } else if (error instanceof NetworkError) { console.error(`خطأ شبكة ${error.statusCode}: ${error.message}`); } else { console.error('خطأ غير معروف:', error); }}هذا النهج يجعل الكود موثقًا ذاتيًا ويبسط التصحيح. أنت دائمًا تعرف أين ولماذا حدث الخطأ.
كتابة الدوال مع الأخطاء: never و discriminated unions
يوفر TypeScript أدوات قوية للعمل مع الأخطاء على مستوى الأنواع. استخدم النوع never للدوال التي ترمي دائمًا استثناءً، و discriminated unions لإرجاع الأخطاء.
function throwError(message: string): never { throw new Error(message);}
// Discriminated union للنتيجةtype Result<T> = | { success: true; data: T } | { success: false; error: string };
function fetchUser(id: number): Result<{ name: string }> { try { // محاكاة طلب if (id <= 0) { return { success: false, error: 'معرف غير صحيح' }; } return { success: true, data: { name: 'آنا' } }; } catch (error) { return { success: false, error: 'خطأ في الشبكة' }; }}
const result = fetchUser(1);if (result.success) { console.log('المستخدم:', result.data.name);} else { console.error('خطأ:', result.error);}نمط Result يسمح بتجنب الاستثناءات الضمنية ويجعل معالجة الأخطاء أكثر وضوحًا وأمانًا من الناحية النوعية.