try / catch معالجة الأخطاء وتضييق catch
آخر تحديث: 2026-10-22
try / catch معالجة الأخطاء وتضييق catch
في معالجة أخطاء TS نقطة ألم بارزتان: الأولى أن err في catch من نوع unknown في الوضع الصارم (فـ JS يمكنها رمي أي قيمة ولا يجرؤ المترجم على افتراض أنها Error) ولا يمكن لمس .message قبل التضييق؛ والثانية أن «احتمال الرمي» لا يظهر في توقيع النوع فلا سبيل للمستدعي لمعرفته. والحلول: ضيّق unknown عبر instanceof؛ وبالنسبة إلى «الفشل المتوقع» انتقل إلى نمط Result الذي يكتب النجاح والفشل في نوع الإرجاع مباشرة.
| المجموعة | الإعداد والتطبيق |
|---|---|
| النوع | بناء الجملة |
| الوضع الصارم | غير مطلوب |
ℹ️ معلومة يحوّل المحرر لغة TypeScript إلى JavaScript ثم يشغّلها (بدون فحص أنواع)؛ راجع ناتج كل مثال لنتيجة فحص الأنواع.
📝 الصيغة
// 1) تضييق unknown
try {
risky();
} catch (err: unknown) {
if (err instanceof Error) console.log(err.message);
else console.log("unknown throw:", err);
}
// 2) نمط Result: نوع اتحادي يعبر عن النجاح أو الفشل
type Result<T> = { ok: true; value: T } | { ok: false; error: string };
function attempt<T>(fn: () => T): Result<T> {
try { return { ok: true, value: fn() }; }
catch { return { ok: false, error: "failed" }; }
}
⚙️ المعاملات
| unknown | نوع متغير catch (وهو الافتراضي في الوضع الصارم): يتسع لأي شيء لكن يجب تضييقه قبل الاستخدام — ومن هنا تأتي الأمانة |
|---|---|
| instanceof | أشيع وسائل التضييق: بعد err instanceof Error يمكن الوصول إلى .message/.stack؛ ويعمل مع أصناف الأخطاء المخصصة أيضًا |
| Result<T> | نوع إرجاع مكتوب يدويًا: { ok: true; value: T } | { ok: false; error }. يجب على المستدعي فحص ok أولًا؛ ولا يمكن لكل فرع الوصول إلا إلى value أو error |
القيمة المُعادة:نوع إرجاع نمط Result اتحاد قابل للتمييز: لا توجد value إلا عندما يكون ok هو true ولا error إلا عندما يكون false — فيُرمَّز «احتمال الفشل» في النوع ذاته، ولا يمر التجميع للمستدعي ما لم يعالج فرع الفشل.
▶ مثال
عدّل الكود أدناه واضغط «جرّب» لرؤية نتيجة التحويل:
الناتج:
caught RangeError: not a positive integer: abc
7 0
{"ok":true,"value":42}
failed: invalid input
(مخرجات التشغيل بعد الترجمة؛ لا يمكن الوصول إلى .message إلا بعد التضييق بـ instanceof — والوصول المباشر إلى err.message من دونه يعطي error TS18046)