🚀 إتقان تنظيم البيانات باستخدام Aliases و Interfaces في TypeScript

بعد أن تعرفنا على الأنواع الأساسية في TypeScript، حان الوقت لنتعلم كيف نجعل الكود الخاص بنا أكثر تنظيماً واحترافية.

في كثير من الأحيان، سنجد أنفسنا نكرر تعريف نفس نوع البيانات في أكثر من مكان. تخيل أن لديك "مستخدم" (User) يتكون من اسم وعمر وبريد إلكتروني، فهل من المنطقي أن تكتب هذه التفاصيل في كل دالة؟ بالطبع لا! هنا يأتي دور Type Aliases و Interfaces.


🏷️ أولاً: أسماء الأنواع المستعارة (Type Aliases)

الـ Type Alias ببساطة هو "اسم مستعار" لنوع معين من البيانات. بدلاً من كتابة النوع الطويل في كل مرة، نقوم بإنشاء اسم مختصر ونستخدمه أينما شئنا.

💡 كيف ننشئ Type Alias؟

نستخدم الكلمة المحجوزة type متبوعة بالاسم الذي نريده، ثم علامة = والنوع.

مثال بسيط جداً: تخيل أننا نريد تعريف نوع لـ "مستخدم" في نظامنا:

// تعريف اسم مستعار لنوع المستخدم
type User = {
    userName: string;
    age: number;
    email: string;
};

// الآن يمكننا استخدام 'User' بدلاً من إعادة كتابة الخصائص
const user1: User = {
    userName: "Ahmed",
    age: 25,
    email: "ahmed@example.com"
};

const user2: User = {
    userName: "Sara",
    age: 22,
    email: "sara@example.com"
};

لماذا استخدمنا هذا الأسلوب؟ 🤔

  1. تقليل التكرار: لم نعد بحاجة لكتابة string و number في كل مرة ننشئ فيها مستخدماً.
  2. سهولة التعديل: إذا قررنا إضافة خاصية جديدة (مثل رقم الهاتف)، سنضيفها في مكان واحد فقط (داخل الـ type User) وسيتم تحديثها في كل مكان في المشروع تلقائياً.

📐 ثانياً: الواجهات (Interfaces)

الـ Interface تشبه إلى حد كبير الـ Type Alias، فهي تُستخدم لتحديد "شكل" (Shape) الكائن (Object). هي بمثابة عقد (Contract) يخبر TypeScript أن هذا الكائن يجب أن يحتوي على هذه الخصائص بالضبط.

💡 كيف ننشئ Interface؟

نستخدم الكلمة المحجوزة interface متبوعة بالاسم، ثم نفتح قوسين {} ونضع الخصائص. (لاحظ أننا لا نستخدم علامة = هنا).

مثال تطبيقي: لنقم بتعريف واجهة لـ "منتج" (Product) في متجر إلكتروني:

// تعريف واجهة للمنتج
interface Product {
    productName: string;
    price: number;
    category: string;
}

// استخدام الواجهة لتعريف متغير
const laptop: Product = {
    productName: "Dell XPS",
    price: 1200,
    category: "Electronics"
};

const mouse: Product = {
    productName: "Logitech Mouse",
    price: 25,
    category: "Accessories"
};

ماذا حدث هنا؟ ✅ لقد أجبرنا المتغيرين laptop و mouse على الالتزام بخصائص الـ Product. إذا حاولت إضافة خاصية غير موجودة في الواجهة أو حذف خاصية أساسية، سيقوم TypeScript بتنبيهك فوراً بوجود خطأ.


⚖️ ما الفرق بين Type Alias و Interface؟

قد تتساءل الآن: "يا مدرس، كلاهما يقومان بنفس العمل تقريباً، فما الفرق؟" 🤔

في المستوى المبتدئ، يمكنك استخدامهما بالتبادل في معظم الحالات، ولكن إليك الفرق الجوهري ببساطة:

  1. الـ Interface: مصممة خصيصاً لوصف "الأجسام" (Objects) وهي مرنة جداً لأنها تسمح بما يسمى "دمج الواجهات" (وهذا سنتعلمه لاحقاً).
  2. الـ Type Alias: أكثر شمولية، فهي لا تصف الأجسام فقط، بل يمكنها وصف أنواع بسيطة (مثل: type ID = string | number).

مثال يوضح قوة الـ Type Alias في الأنواع البسيطة:

// هنا لا يمكننا استخدام Interface، بل يجب استخدام Type
type Status = "Active" | "Inactive" | "Pending";

let userStatus: Status = "Active"; // صحيح
// let userStatus: Status = "Deleted"; // خطأ! لأن القيمة ليست من ضمن الخيارات المحددة

🛠️ ملخص سريع للمقارنة

وجه المقارنة Type Alias (type) Interface (interface)
الاستخدام الأساسي تعريف اسم لنوع بيانات تعريف هيكل كائن (Object)
المرونة يمكنها وصف أنواع بدائية أو مجمعة متخصصة في وصف الكائنات
طريقة الكتابة تستخدم علامة = لا تستخدم علامة =