تخطي إلى المحتوى الرئيسي

أنواع الكائنات (Object Types) والأسماء المستعارة للأنواع (Type Aliases) في TypeScript

أنواع الكائنات (Object Types) والأسماء المستعارة للأنواع (Type Aliases) في TypeScript

مقدمة عن الأنواع والأسماء المستعارة للأنواع

في TypeScript، تعتبر الأنواع جزءاً أساسياً لتنظيم البيانات وضمان جودتها. تعتبر TypeScript لغة برمجة قوية ومتعددة الاستخدامات توفر مجموعة غنية من الأدوات والميزات لتطوير تطبيقات الويب والهواتف المحمولة وغيرها.

لماذا فهم الأنواع والأسماء المستعارة للأنواع مهم في TypeScript؟

فهم الأنواع والأسماء المستعارة للأنواع يساعد المطورين على:

  • تحديد نوع البيانات المستخدم وتجنب الأخطاء الناتجة عن التعامل مع بيانات غير محددة النوع.
  • ضمان ثبات البيانات ومنع التغييرات غير المتوقعة في القيم.
  • تحسين أداء التطبيق بتقليل التحويلات الضائعة بين الأنواع.
  • تسريع عملية التطوير وتصحيح الأخطاء بوجود رسائل خطأ أكثر وضوحاً وتفصيلاً.
  • تسهيل التعاون بين المطورين عن طريق توحيد التوقعات وتقليل الصراعات.

أنواع الكائنات في TypeScript

في TypeScript، يمكن تعريف الأنواع على النحو التالي:

  • الأنواع البدائية: تشمل الأعداد الصحيحة والأعداد العشرية والنصوص والقيم المنطقية.
  • أنواع الكائنات: تشمل تعريف أنواع الكائنات المخصصة وتنظيم البيانات المعقدة.
  • أنواع الاتحاد: تجمع بين قيم من أنواع مختلفة.
  • أنواع التعابير: تستخدم لتحديد قيم متغيرة أو ثابتة.
  • أنواع الواجهات: تعريف مجموعة من الخصائص والطرق لكيانات معينة.

الأسماء المستعارة للأنواع في TypeScript

الأسماء المستعارة للأنواع في TypeScript تعتبر طريقة لإعادة تسمية الأنواع وتبسيط الاستخدام. فيما يلي الأنواع المتاحة في TypeScript والأسماء المستعارة المقابلة:

  • Number: الاسم للأنواع البدائية للأعداد الصحيحة والأعداد العشرية.
  • String: الاسم للنصوص.
  • Boolean: الاسم للقيم المنطقية.
  • BigInt: الاسم للأعداد الصحيحة الكبيرة جداً.
  • Symbol: الاسم للأنواع الفريدة والمعرفات.

استخدام الأنواع والأسماء المستعارة للأنواع في الكود

في هذا القسم، سنستكشف كيف يمكن استخدام الأنواع والأسماء المستعارة للأنواع في الكود لتحسين القراءة والصيانة.

استخدام الأنواع البدائية: في TypeScript، يمكن استخدام الأنواع البدائية مباشرة دون الحاجة لتحديد نوعها:

let number = 123;
let string = "Hello World!";
let boolean = true;
let bigInt = 2n ** 53n;
let symbol = Symbol("mySymbol");

استخدام الأسماء المستعارة للأنواع: يمكن استخدام الأسماء المستعارة للأنواع لتسهيل القراءة وتحسين هيكلة الكود:

type MyBigInt = bigint;
type MyString = string;
type MyBoolean = boolean;
type MySymbol = symbol;

let bigNumber: MyBigInt = 2n ** 53n;
let aliasString: MyString = "Hello World!";
let booleanValue: MyBoolean = true;
let uniqueSymbol: MySymbol = Symbol("mySymbol");

أنواع الكائنات الأساسية في TypeScript

في TypeScript، تعتبر الكائنات الأساسية هي الأساس الذي تبنى عليه الأنواع الأخرى:

  • number: يمثل الأعداد الصحيحة والعشرية والعمليات الحسابية عليها.
  • string: يمثل النصوص والتعامل معها.
  • boolean: يمثل القيم المنطقية والعمليات المتعلقة بها.
  • null: يمثل القيمة الفارغة المقصودة.
  • undefined: يمثل القيمة غير المعرفة للمتغيرات غير المهيأة.
  • any: يستخدم لتحديد نوع الكائن مؤقتاً ويتجاوز فحص الأنواع الصارم.

الكائنات (Objects)

الكائنات هي عناصر أساسية في لغة TypeScript ويمكن تعريفها باستخدام let أو const بواسطة الأقواس المعقوفة {}:

let myObject = {
    name: "John Doe",
    age: 30,
    isAdult: true
};

واجهات الكائنات (Interfaces)

تسمح لنا بتحديد عقد لمجموعة من الخصائص والقيم المتوقعة من كائن معين:

interface Person {
    name: string;
    age: number;
    isAdult: boolean;
}

let myPerson: Person = {
    name: "John Doe",
    age: 30,
    isAdult: true
};

الأنواع الثابتة (Static / Explicit Types)

يمكن استخدام التصريح الصريح بالأنواع لتحديد المتطلبات بدقة للكائنات، القوائم، والمصفوفات لتقليل الأخطاء في وقت التطوير:

// مع الأنواع البدائية
type PositiveNumber = number;
let myPositiveNumber: PositiveNumber = 10;

// مع الكائنات
type PersonType = {
    name: string;
    age: number;
    isAdult: boolean;
};

let personItem: PersonType = {
    name: "John Doe",
    age: 30,
    isAdult: true
};

// مع القوائم والمصفوفات
type MyList = string[];
let myList: MyList = ["John Doe", "Jane Doe", "Bob Doe"];

type MyArray = number[];
let myArray: MyArray = [1, 2, 3];

الأسماء المستعارة للأنواع (Type Aliases) بالتفصيل

الأسماء المستعارة للأنواع هي طريقة لإنشاء أسماء مخصصة تكون بمثابة اختصار أو مرجع لنوع أساسي أو مركب:

// اسم مستعار لنوع رقم
type NumberAlias = number;
let num: NumberAlias = 10;

// اسم مستعار لنوع عدد عشري
type DecimalAlias = number;
let decimal: DecimalAlias = 3.14;

// اسم مستعار للنوع البولياني
type BooleanAlias = boolean;
let booleanState: BooleanAlias = true;

// اسم مستعار يقبل القيمة الفارغة (Nullable)
type NullableNumber = number | null;
let numberValue: NullableNumber = 10;
let nullValue: NullableNumber = null;

// أنواع تمثل اتحاد الأرقام
type NumericValue = number;
let integerVal: NumericValue = 10;
let floatVal: NumericValue = 10.123;

الأسماء المستعارة للأنواع المحلية (Local Type Aliases)

أحياناً، يكون تعريف نوع معين ذا صلة بسياق محدد للغاية مثل داخل دالة واحدة، وهنا يأتي دور الأسماء المستعارة للأنواع المحلية المعرفة داخل نطاق دالة (Function Scope):

  • التغليف (Encapsulation): الحفاظ على تعريفات الأنواع وثيقة الصلة بالمنطق الخاص بها، مما يقلل الارتباطات غير الضرورية.
  • تحسين قابلية القراءة: تقليل الحاجة لتكرار التعريفات المضمنة الطويلة داخل توقيع الدالة.
  • تجنب تضارب الأسماء: عزل الأنواع داخل نطاق الدالة يحمي من التعارض مع أسماء عامة في المشروع أو المكتبات الخارجية.
function processTransaction() {
    // اسم مستعار محلي خاص بالدالة فقط
    type TransactionPayload = {
        amount: number;
        currency: "USD" | "EUR";
        senderId: string;
    };

    const currentTx: TransactionPayload = {
        amount: 250,
        currency: "USD",
        senderId: "USR-99"
    };

    console.log(`تم تحويل: ${currentTx.amount} ${currentTx.currency}`);
}

الأسماء المستعارة للأنواع العالمية (Global Type Aliases)

تتمتع الأسماء المستعارة للأنواع العالمية بنطاق وصول يمتد ليشمل البرنامج بأكمله أو عبر تصديرها واستيرادها بين الوحدات البرمجية:

  • الوصول الشامل وإعادة الاستخدام: تعريف نماذج البيانات المركزية (مثل استجابات الـ API أو كائنات المستخدمين) لضمان توحيد البنية عبر كل ملفات المشروع.
  • تقليل التكرار (DRY): منع إعادة كتابة نفس الهياكل البرمجية في كل ملف بصورة منفصلة.

أنواع الكائنات المعقدة: الاتحاد (Union) والتقاطع (Intersection)

تسمح أنواع الاتحاد بتمثيل متغيرات قد تتخذ أكثر من نوع ممكن باستخدام العامل |:

type Status = "success" | "error";
type UserID = number | string;

function displayUserID(id: UserID) {
    console.log(`معرف المستخدم: ${id}`);
    if (typeof id === 'string') {
        console.log("المعرف من نوع سلسلة نصية.");
    } else {
        console.log("المعرف من نوع رقم.");
    }
}

displayUserID(123);
displayUserID("abc-456");

تزداد قوة أنواع الاتحاد عند استخدامها لنمذجة أحداث مختلفة وتمييزها (Discriminated Unions):

type ClickEvent = {
    type: "click";
    x: number;
    y: number;
};

type HoverEvent = {
    type: "hover";
    elementId: string;
};

type AppEvent = ClickEvent | HoverEvent;

function handleEvent(event: AppEvent) {
    if (event.type === "click") {
        console.log(`إحداثيات النقر: ${event.x}, ${event.y}`);
    } else {
        console.log(`تم التمرير فوق العنصر: ${event.elementId}`);
    }
}

أنواع الكائنات والمصفوفات (Arrays of Object Types)

تُمثل مصفوفات الكائنات بنى البيانات الواقعية الأكثر استخداماً في التطبيقات الحديثة لإدارة القوائم والسجلات:

type User = {
    id: number;
    name: string;
    email: string;
    isActive: boolean;
};

// تعريف مصفوفة من كائنات User
const users: User[] = [
    { id: 1, name: "أحمد محمد", email: "ahmed@example.com", isActive: true },
    { id: 2, name: "فاطمة علي", email: "fatima@example.com", isActive: false },
    { id: 3, name: "خالد سعيد", email: "khalid@example.com", isActive: true }
];

// الوصول إلى عناصر المصفوفة وخصائص الكائنات داخلها
console.log(users[0].name);  // "أحمد محمد"
console.log(users[1].email); // "fatima@example.com"

// استخدام دوال المصفوفات القياسية مع الأمان النوعي الكامل
const activeUsers = users.filter(user => user.isActive);
console.log(activeUsers.length); // 2

أنواع الكائنات والمصفوفات المتقدمة: الأنواع المخططة (Mapped Types)

تُعد الأنواع المخططة إحدى الميزات الأكثر قوة في TypeScript، حيث تسمح لنا بإنشاء أنواع جديدة بناءً على أنواع موجودة مسبقاً عن طريق تحويل خصائصها والتكرار على مفاتيحها باستخدام الصيغة [P in keyof T]:

  • تعتمد على أدوات مساعدة شائعة مثل Partial<T> و Readonly<T> و Pick<T, K> و Omit<T, K>.
  • إمكانية إنشاء أنواع مخططة مخصصة تلبي احتياجات المشروع المحددة.

مثال: إنشاء نوع مخطط يجعل كافة الخصائص تقبل القيم الفارغة (Nullable)

type BaseUser = {
    id: number;
    name: string;
    email: string;
};

// تعريف نوع مخطط مخصص لتحويل كافة الحقول إلى حقول قابلة لأن تكون null
type Nullable<T> = {
    [P in keyof T]: T[P] | null;
};

type NullableUser = Nullable<BaseUser>;

const userDraft: NullableUser = {
    id: 1,
    name: null,       // مسموح به الآن بفضل النوع المخطط
    email: "user@test.com"
};

console.log(userDraft);

خلاصة المقال

توفر الأنواع والأسماء المستعارة للأنواع (Type Aliases) في TypeScript إطاراً متكاملاً لإدارة البيانات: بدءاً من الأنواع البدائية البسيطة والكائنات الأساسية، مروراً بالأسماء المستعارة المحلية والعالمية، وصولاً إلى أنواع الكائنات المعقدة ومصفوفات السجلات والأنواع المخططة (Mapped Types). إتقان هذه الميزات يمنح مشاريعك البرمجية أماناً نوعياً صارماً وسهولة كبيرة في التطوير والصيانة.


اكتشاف المزيد من كود التطور

اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.

MOHAMMAD ABU KASHREEF

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

اترك رد