emit وon الآمنان نوعيًا
أَلزموا بصحة الحمولات عند الإرسال والاستماع
emit وon الآمنان نوعيًا درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
توقيع emit آمن من ناحية الأنواع
اجعل emit عامًا بالنسبة إلى اسم الحدث K. وعندها تصبح وسيطة الحمولة Events[K]، لذلك يجب أن يتطابق الاسم والحمولة.
interface Events { login: { userId: string }; logout: void }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {
console.log("emit", event, JSON.stringify(payload));
}
emit("login", { userId: "u1" });الحمولة الخاطئة تؤدي إلى خطأ أثناء الترجمة
إذا لم تتطابق الحمولة مع اسم الحدث، يرفضها TypeScript. ويربط النوع العام بين المعاملين.
interface Events { login: { userId: string } }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {}
// emit("login", { id: "u1" }); // Error: id is not userId
emit("login", { userId: "u1" });
console.log("ok");رفض أسماء الأحداث غير المعروفة
بما أن K extends keyof Events، لا يمكنك إصدار حدث غير موجود في الخريطة.
interface Events { login: { userId: string } }
function emit<K extends keyof Events>(event: K, payload: Events[K]) {}
// emit("signup", { userId: "x" }); // Error: "signup" not a key
emit("login", { userId: "x" });
console.log("only known events");معالجات محددة الأنواع باستخدام on
تسجّل الطريقة on معالجًا تكون وسيطته من النوع Events[K] بالضبط، لذلك تتلقى المعالجات حمولات محددة النوع بشكل صحيح.
interface Events { login: { userId: string }; logout: void }
function on<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void) {
console.log("subscribed to", event);
}
on("login", (p) => console.log(p.userId));يُستنتج نوع وسيطة المعالج
لا تحتاج إلى كتابة نوع وسيطة المعالج؛ إذ يستنتجه TypeScript من اسم الحدث، مما يوفّر الإكمال التلقائي الكامل داخل جسم المعالج.
interface Events { message: { text: string } }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("message", (p) => {
// p is { text: string }
console.log(p.text.toUpperCase());
});معالجة الأحداث التي لا تحمل حمولات
بالنسبة إلى أحداث void، لا يأخذ المعالج أي وسيطة مفيدة ببساطة. ويمكنك استدعاء معالج الحدث من دون بيانات.
interface Events { logout: void }
function on<K extends keyof Events>(event: K, handler: (p: Events[K]) => void) {}
on("logout", () => console.log("logged out"));دمج emit وon
يشكّل emit وon معًا نظام نشر/اشتراك آمنًا من ناحية الأنواع. ويؤدي إصدار حدث إلى تسليم حمولة محددة النوع بشكل صحيح إلى معالجاته.
interface Events { ping: { at: number } }
type Handler<K extends keyof Events> = (p: Events[K]) => void;
const handlers: { ping: Handler<"ping">[] } = { ping: [] };
function on<K extends keyof Events>(e: K, h: Handler<K>) { handlers[e].push(h as Handler<"ping">); }
function emit<K extends keyof Events>(e: K, p: Events[K]) { handlers[e].forEach(h => h(p as Events["ping"])); }
on("ping", p => console.log("at", p.at));
emit("ping", { at: 5 });تقييد موضع الحمولة
يضمن النوع العام التحقق من وسيطة الحمولة مقابل الحدث المختار، فيكتشف حالات عدم التطابق في موضع الاستدعاء، لا في عمق المعالج.
interface Events { add: { x: number; y: number } }
function emit<K extends keyof Events>(e: K, p: Events[K]) {
return e;
}
emit("add", { x: 1, y: 2 });
// emit("add", { x: 1 }); // Error: y missing
console.log("payload checked");الإكمال التلقائي لأسماء الأحداث
بما أن المعامل الأول هو keyof Events، تكمل المحررات أسماء الأحداث الصالحة تلقائيًا أثناء كتابة الاستدعاء.
interface Events { open: void; close: void }
function emit<K extends keyof Events>(e: K, p: Events[K]) {}
// Typing emit(" suggests "open" and "close"
emit("open", undefined as void);
console.log("autocompleted names");لماذا تُعد الأنواع العامة ضرورية هنا
من دون نوع عام، ستحتاج إلى توقيعات زائدة لكل حدث. أما توقيع عام واحد فيتوسع تلقائيًا ليتعامل مع أي عدد من الأحداث.
interface Events { a: { x: number }; b: { y: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return p; }
console.log(emit("a", { x: 1 }), emit("b", { y: "hi" }));نمط قابل لإعادة الاستخدام
يُعد النمط emit<K>(event, payload) وon<K>(event, handler) جوهر كل باعث آمن من ناحية الأنواع، وسنضعه في فئة في الدرس التالي.
interface Events { tick: { n: number } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
function on<K extends keyof Events>(e: K, h: (p: Events[K]) => void) { return e; }
console.log(emit("tick", { n: 1 }), on("tick", p => p.n));تحقق سريع: emit وon محددا الأنواع
اختبر مدى فهمك لـ emit وon الآمنين من ناحية الأنواع.
مراجعة: emit وon الآمنان من ناحية الأنواع
أنشأت توقيعي emit وon عامين تكون فيهما الحمولة Events[K]، فأصبحت أسماء الأحداث قابلة للإكمال التلقائي، وتحولت الحمولات الخاطئة إلى أخطاء أثناء الترجمة، واستُنتجت أنواع معاملات المعالجات.
interface Events { login: { userId: string } }
function emit<K extends keyof Events>(e: K, p: Events[K]) { return e; }
console.log(emit("login", { userId: "u1" }));تعلم TypeScript مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 101
- الدروس
- 352
الأسئلة الشائعة
هل درس «emit وon الآمنان نوعيًا» مجاني؟
نعم — نص درس «emit وon الآمنان نوعيًا» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «emit وon الآمنان نوعيًا»؟
أَلزموا بصحة الحمولات عند الإرسال والاستماع تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟
لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «emit وon الآمنان نوعيًا»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟
نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحديد أنواع خرائط الأحداث
- emit وon الآمنان نوعيًا
- فئة باعث الأحداث العامة
- استنتاج وسائط المستمعين