Promise<T> الأنواع غير المتزامنة

آخر تحديث: 2026-10-22

Promise<T> الأنواع غير المتزامنة

تدور الأنواع غير المتزامنة حول Promise<T>: فنوع إرجاع الدالة async يُغلَّف تلقائيًا بطبقة Promise، بينما يفك await ذلك على مستوى القيم؛ ويقوم نوع الأداة Awaited<T> بالعمل نفسه على مستوى الأنواع (يفك الـ Promise المتداخلة إلى أقصاها). وحالما تفهم «ما النوع المحمول داخل الـ Promise» صار لكل متغير في الشيفرة غير المتزامنة نوع دقيق.

المجموعةالإعداد والتطبيق
النوعبناء الجملة
الوضع الصارمغير مطلوب

ℹ️ معلومة يحوّل المحرر لغة TypeScript إلى JavaScript ثم يشغّلها (بدون فحص أنواع)؛ راجع ناتج كل مثال لنتيجة فحص الأنواع.

📝 الصيغة

// الدوال async: نوع القيمة المُعادة يُلف دائمًا بـ Promise<T>
async function fetchUser(id: number): Promise<User> {
  const res = await getJson("/users/" + id); // await يفكّ طبقة من الـ Promise
  return res;                                 // القيمة المُعادة هي User
}

// Awaited<T>: await على مستوى الأنواع
type A = Awaited<Promise<User>>;        // User
type B = Awaited<Promise<Promise<User>>>; // User — حتى المتداخلة تُفكّ إلى النهاية

⚙️ المعاملات

Promise<T>حاوية عامة مدمجة؛ T هو نوع القيمة التي ستحصل عليها في نهاية الأمر. وتعمل مع async/await من دون أي استيراد
asyncمُعدِّل دوال: يسمح باستخدام await داخل المتن؛ ويُغلَّف قيمة الإرجاع تلقائيًا بـ Promise — فالقيمة العادية T تصبح Promise<T> وما كان Promise أصلًا لا يُغلَّف مرتين
Awaited<T>نوع أداة مدمج يحاكي الأثر النوعي لـ await: يفك Promise ليعطي T، ويفك التداخل تكراريًا، ويمرر الأنواع غير الـ Promise دون تغيير

القيمة المُعادة:نوع إرجاع الدالة async هو Promise<T>: فسواء أعاد متن الدالة قيمة عادية T أو Promise<T> فالنوع النهائي Promise<T> (ولن يظهر أبدًا Promise<Promise<T>>).

▶ مثال

عدّل الكود أدناه واضغط «جرّب» لرؤية نتيجة التحويل:

الناتج:

{"id":7,"title":"Write TypeScript notes","done":false}
todo#7 title="Write TypeScript notes" done=false

(مخرجات التشغيل بعد الترجمة؛ يُستنتج todo بوصفه Todo عبر await — فمن دونه تحصل على Promise<Todo> والوصول المباشر إلى todo.id خطأ نوعي)

💡 نقاط مهمة

ℹ️ معلومة داخل دالة async تتعادل الصيغتان return T وreturn Promise<T> تمامًا ولن يتكدس النوع إلى Promise<Promise<T>> — والـ Awaited<T> هي القاعدة ذاتها وقد تحولت إلى نوع أداة.
💡 تلميح نوع نتيجة Promise.all صف (tuple): فالصيغة Promise.all([p1, p2]) نوعها Promise<[A, B]> مع الحفاظ على نوع كل موضع منفردًا — وawait واحدة تحصل على كل القيم مع أنواع دقيقة لكل منها.
⚠️ تنبيه الاستثناءات المرمية داخل دالة async لا تُرمى بشكل متزامن بل تتحول إلى Promise مرفوض (rejected): يجب لفّ await بـ try/catch أو تسلسل .catch() وإلا حصلت على unhandled rejection؛ ونوع الإرجاع Promise<T> بذاته لا يكشف «احتمال الفشل».
المزيد من الحالات قادم قريبًا.

📚 دروس ذات صلة

❓ أسئلة شائعة

س ماذا تفعل Awaited<T> ومتى أستخدمها؟
ج تحاكي await على مستوى الأنواع: تتحول Promise<T> إلى T وتفك الـ Promise المتداخلة كليًا وتمرر غيرها دون تغيير. نادرًا ما تستخدمها مباشرة — إنها تظهر غالبًا داخل تعريفات الأنواع المدمجة (كـ Promise.all وأنواع إرجاع دوال async) وعندما تحتاج أدواتك المخصصة إلى «فك Promise»، مثل Unwrap<T> = Awaited<T>.
س ماذا يحدث إذا نسيت await؟
ج تحصل على Promise<Todo> لا Todo: فالوصول إلى .id خطأ نوعي (أوضح تحت strictNullChecks)، وفي التشغيل فهو «مهمة لم تنته بعد». ولن ينفذ await عنك TypeScript — كلما رأيت نوع Promise اسأل نفسك: هل أحتاج await؟
س هل يجب كتابة Promise<T> صراحة لدوال async؟
ج لا — يشتق الاستنتاج Promise<T> من تعليمات return. والكتابة الصريحة تعود بالنفع في API العمومية (فالعقد مرئي وأخطاء التوقيع تظهر أولًا عند تعديل التنفيذ)؛ أما الدوال الداخلية الصغيرة فاتركها للاستنتاج.
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%