تضييق النوع اعتمادًا على المميّز
دعوا TypeScript يضيّق أنواع البدائل في عبارات switch
تضييق النوع اعتمادًا على المميّز درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
التضييق استنادًا إلى الخاصية المميّزة
بعد التحقق من الخاصية المميّزة، يضيّق TypeScript الاتحاد إلى العضو المطابق، ويتيح الوصول إلى حقوله الخاصة. وهذه هي الفائدة الأساسية من هذا النمط.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape) {
if (s.kind === "circle") return Math.PI * s.radius ** 2;
return s.side ** 2;
}
console.log(area({ kind: "circle", radius: 2 }).toFixed(2));استخدام switch مع الخاصية المميّزة
يُعد استخدام switch مع الخاصية المميّزة أوضح طريقة لمعالجة كل نوع مختلف. وداخل كل case، يُضيّق النوع تلقائيًا.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
}
}
console.log(area({ kind: "square", side: 5 }));الحقول الخاصة بكل عضو في كل حالة
في حالة "circle"، يتوفر s.radius، بينما لا يتوفر s.side. إذ يعرف TypeScript بدقة العضو الذي تتعامل معه.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function describe(s: Shape) {
switch (s.kind) {
case "circle": return "r=" + s.radius;
case "square": return "side=" + s.side;
}
}
console.log(describe({ kind: "circle", radius: 9 }));التضييق باستخدام if
لا تحتاج إلى استخدام switch؛ فمقارنة بسيطة باستخدام if مع الخاصية المميّزة تحقق التضييق بالفاعلية نفسها.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function perimeter(s: Shape): number {
if (s.kind === "circle") {
return 2 * Math.PI * s.radius;
}
return 4 * s.side;
}
console.log(perimeter({ kind: "square", side: 3 }));يفشل الوصول إلى الحقل الخطأ
قبل إجراء التضييق، لا يمكنك الوصول إلى حقل خاص بعضو معين. إذ يُبلغ TypeScript عن خطأ لأن الخاصية غير موجودة في كل عضو.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function broken(s: Shape) {
// Error: radius does not exist on Square
// return s.radius;
return s.kind;
}
console.log(broken({ kind: "square", side: 1 }));التضييق باستخدام الخصائص المميّزة المنطقية
بالنسبة إلى اتحاد من النوع { ok: true } | { ok: false }، يؤدي التحقق باستخدام if (r.ok) إلى التضييق نحو عضو النجاح.
type Result =
| { ok: true; data: string }
| { ok: false; error: string };
function handle(r: Result): string {
if (r.ok) return "Data: " + r.data;
return "Error: " + r.error;
}
console.log(handle({ ok: false, error: "boom" }));التضييق عبر الإرجاع المبكر
يؤدي الإرجاع المبكر عند أحد الأنواع المختلفة إلى تضييق بقية الشيفرة لتشمل الأنواع الأخرى، وهي طريقة واضحة لمعالجة الحالات واحدة تلو الأخرى.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function label(s: Shape): string {
if (s.kind === "circle") return "circle";
// s is now narrowed to Square here
return "square with side " + s.side;
}
console.log(label({ kind: "square", side: 8 }));الدمج مع شروط أخرى
يمكنك دمج التحقق من الخاصية المميّزة مع منطق آخر. ويحافظ TypeScript على التضييق ما دام شرط الخاصية المميّزة صحيحًا في ذلك الفرع.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function bigCircle(s: Shape): boolean {
return s.kind === "circle" && s.radius > 100;
}
console.log(bigCircle({ kind: "circle", radius: 150 }));التضييق في مرشحات المصفوفات
يعمل التضييق داخل دوال الاستدعاء العكسي أيضًا. إذ يجري هنا التحقق من كل شكل على حدة أثناء التكرار.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
const shapes: Shape[] = [
{ kind: "circle", radius: 1 },
{ kind: "square", side: 2 }
];
shapes.forEach(s => {
if (s.kind === "circle") console.log("c", s.radius);
else console.log("s", s.side);
});تحافظ قيم الإرجاع من switch على أمان الأنواع
عندما يعالج switch كل الحالات ويُرجع قيمة، يستنتج TypeScript نوع إرجاع دقيقًا من اتحاد نتائج جميع الحالات.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function tag(s: Shape) {
switch (s.kind) {
case "circle": return s.radius;
case "square": return s.side;
}
}
console.log(tag({ kind: "circle", radius: 4 }));جمع عناصر التضييق
سواء استخدمت switch أو if، فإن التحقق من الخاصية المميّزة هو ما يتيح الوصول بأمان إلى حقول العضو. وسنضمن في الخطوة التالية معالجة كل حالة.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
return s.kind === "circle" ? Math.PI * s.radius ** 2 : s.side ** 2;
}
console.log(Math.round(area({ kind: "circle", radius: 10 })));تحقق سريع: التضييق
اختبر فهمك لتضييق الاتحادات المميّزة.
مراجعة: التضييق استنادًا إلى الخاصية المميّزة
رأيت أن التحقق من الخاصية المميّزة باستخدام switch أو if يضيّق الاتحاد إلى عضو واحد، ويكشف فقط الحقول الخاصة بذلك العضو. وتحافظ عمليات الإرجاع المبكر والشروط المدمجة على التضييق.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
const s: Shape = { kind: "square", side: 7 };
console.log(s.kind === "square" ? s.side : 0);الأسئلة الشائعة
هل درس «تضييق النوع اعتمادًا على المميّز» مجاني؟
نعم — نص درس «تضييق النوع اعتمادًا على المميّز» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «تضييق النوع اعتمادًا على المميّز»؟
دعوا TypeScript يضيّق أنواع البدائل في عبارات switch تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟
لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «تضييق النوع اعتمادًا على المميّز»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟
نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- بناء الاتحادات المميّزة
- تضييق النوع اعتمادًا على المميّز
- التحقق من اكتمال الحالات باستخدام never
- نمذجة آلات الحالات