🔷 شرح TypeScript

حُرّاس الأنواع (Type Guards)

ما هو تضييق النوع (Narrowing)؟

عند التعامل مع اتحاد أنواع، نحتاج معرفة النوع الفعلي قبل استخدامه. حُرّاس الأنواع تساعد TypeScript على تضييق النوع داخل كتلة معيّنة.

الحارس typeof

للأنواع البدائية (string, number, boolean):

function format(value: string | number) {
  if (typeof value === "string") {
    return value.toUpperCase();   // TypeScript يعرف أنه string
  }
  return value.toFixed(2);        // وهنا number
}

الحارس instanceof

للأصناف والكائنات:

class Dog { bark() {} }
class Cat { meow() {} }

function speak(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark();
  } else {
    animal.meow();
  }
}

الحارس in

لفحص وجود خاصية في كائن:

type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
  if ("swim" in animal) {
    animal.swim();
  } else {
    animal.fly();
  }
}

الحُرّاس المخصّصة (Type Predicates)

دالة تُرجع param is Type لتعليم TypeScript بالنوع:

interface User { name: string; }

function isUser(obj: unknown): obj is User {
  return typeof obj === "object" && obj !== null && "name" in obj;
}

const data: unknown = { name: "علي" };
if (isUser(data)) {
  console.log(data.name);   // آمن — TypeScript يعرف أنه User
}

تضييق بالقيمة (Discriminated Unions)

نمط قويّ: حقل مشترك يميّز كل نوع:

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;
  }
}

أخطاء شائعة

  • استخدام as للتأكيد القسري بدل حارس نوع آمن.
  • نسيان فحص null ضمن typeof obj === "object" (لأن typeof null هو "object").

🎯 التالي: الأنواع المتقدّمة — الشرطية والمُعيَّنة.