مصفوفات الكائنات في TypeScript: دليل كامل مع أمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

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

\n\n

هل سبق لك أن كتبت كودًا بلغة TypeScript وفجأة ظهر لك خط أحمر من IDE عندما حاولت إضافة كائن إلى مصفوفة؟ مألوف، أليس كذلك؟ سؤال "How can I define an array of objects?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. وليس من دون سبب: بدون كتابة الأنواع الصحيحة لمصفوفات الكائنات، يتحول كودك إلى مصدر للأخطاء والصداع.

\n\n

في هذا الدليل التعليمي، سنستعرض جميع طرق تعريف مصفوفة الكائنات في TypeScript - من البسيطة إلى المتقدمة. ستتعلم كيفية تجنب الأخطاء الشائعة، وكيفية استخدام الواجهات، وكيفية جعل كودك ليس فقط عمليًا بل أيضًا جميلًا. هيا بنا!

\n\n

لماذا لا يعمل [] البسيط؟

\n\n

لنفترض أنك تكتب:

\n\n
let users = [];
\n\n

يرى TypeScript هذا على أنه never[] - مصفوفة لا يجب أن تحتوي على عناصر أبدًا. حاول إضافة كائن إليها:

\n\n
users.push({ name: 'آنا', age: 25 }); // خطأ!
\n\n

سيصرخ IDE: "Argument of type '{ name: string; age: number; }' is not assignable to parameter of type 'never'." لا يعرف TypeScript ما الذي تنوي تخزينه في المصفوفة، لذلك يمنع أي إضافات.

\n\n

الحل هو تحديد نوع المصفوفة بوضوح. دعنا نستعرض جميع الخيارات.

\n\n

الطريقة 1: تعليق النوع الأساسي - الأقواس المربعة

\n\n

أبسط وأكثر طريقة بديهية هي استخدام الصياغة Type[]:

\n\n
let users: { name: string; age: number }[] = [];\n\nusers.push({ name: 'آنا', age: 25 }); // ✅ يعمل\nusers.push({ name: 'إيفان', age: 30 }); // ✅ يعمل\n
\n\n

هنا نقول لـ TypeScript: "يا هذا، هذه مصفوفة كائنات، كل منها يحتوي على خصائص name (سلسلة نصية) و age (رقم)". IDE الآن راضٍ، الإكمال التلقائي يعمل، ويتم اكتشاف أخطاء الأنواع في مرحلة التجميع.

\n\n

العيب: إذا كان هيكل الكائن معقدًا، يصبح الوصف مباشرة في التعليق ضخمًا. لمثل هذه الحالات، تم اختراع الواجهات.

\n\n

الطريقة 2: الواجهات - أفضل صديق لك

\n\n

تسمح لك الواجهات بإخراج وصف الكائن إلى كيان منفصل وإعادة استخدامه. هذا يجعل الكود أنظف وأوضح:

\n\n
interface User {\n  id: number;\n  name: string;\n  age: number;\n  email?: string; // خاصية اختيارية\n}\n\nlet users: User[] = [];\n\nusers.push({ id: 1, name: 'آنا', age: 25 });\nusers.push({ id: 2, name: 'إيفان', age: 30, email: 'ivan@example.com' }); // ✅\n
\n\n

الآن إذا حاولت إضافة كائن بدون حقل id أو بنوع خاطئ، سيعطيك TypeScript خطأ. الواجهات مفيدة بشكل خاص عندما يتم استخدام نفس نوع الكائن في عدة أماكن.

\n\n

وماذا عن type؟

\n\n

بدلاً من interface يمكنك استخدام type:

\n\n
type User = {\n  id: number;\n  name: string;\n  age: number;\n};\n\nlet users: User[] = [];
\n\n

الفرق بين interface و type هو موضوع لمقال منفصل. بالنسبة لمصفوفات الكائنات، يمكن استخدام كلا الخيارين، لكن interface يُستخدم غالبًا لوصف أشكال الكائنات.

\n\n

الطريقة 3: صياغة Generic Array<Type>

\n\n

طريقة بديلة هي استخدام الأدوية (Generics):

\n\n
let users: Array<{ name: string; age: number }> = [];\n\n// أو مع واجهة:\nlet users: Array<User> = [];\n
\n\n

كلا الصياغتين (Type[] و Array<Type>) تعملان بنفس الطريقة. الاختيار مسألة ذوق وسياق. شخصيًا، أفضل Type[] للأنواع البسيطة و Array<Type> للتركيبات المعقدة للأدوية. لكن الأهم هو أن تكون متسقًا في المشروع.

\n\n

الطريقة 4: إنشاء مصفوفة بكائنات أولية

\n\n

غالبًا ما تحتاج المصفوفة ليس فقط إلى التصريح عنها، بل أيضًا إلى ملئها بالبيانات فورًا. TypeScr

المدونات

توصيات الكتب