Array<Type> مقابل Type[] في TypeScript: 5 أخطاء قاتلة وكيفية تجنبها

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

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

ابدأ الدورة

Array<Type> مقابل Type[] في TypeScript: معركة الصياغة التي يجب أن تربحها

\n\n

إذا كنت قد كتبت أي كود بلغة TypeScript من قبل، فبالتأكيد رأيت طريقتين للإعلان عن مصفوفة أرقام:

\n\n
const numbers1: number[] = [1, 2, 3];\nconst numbers2: Array<number> = [1, 2, 3];
\n\n

كلا الخيارين يعملان. كلاهما يتم تجميعهما. كلاهما TypeScript صحيح. فلماذا كل هذا الجدل حولهما؟ لماذا جمع هذا السؤال على Stack Overflow آلاف المشاهدات؟ والأهم من ذلك - كيف لا تقع في الأخطاء التي قد تدمر مشروعك؟

\n\n

دعنا نفهم الأمر مرة واحدة وإلى الأبد. بدون نظرية مملة. فقط ما سيفيدك حقًا في الميدان.

\n\n

شرح موجز: ما هو ما

\n\n

صياغة Type[] (صياغة المصفوفة الحرفية)

\n\n

هذه هي الطريقة الأكثر شيوعًا للإعلان عن مصفوفة في TypeScript. لقد جاءت من JavaScript وتبدو طبيعية:

\n\n
let fruits: string[] = ['apple', 'banana', 'cherry'];\nlet matrix: number[][] = [[1, 2], [3, 4]]; // مصفوفة من المصفوفات
\n\n

قصيرة، قابلة للقراءة، بديهية. في 90% من الحالات، هذا يكفي.

\n\n

صياغة Array<Type> (صياغة الأدوية العامة)

\n\n

هذه هي صيغة الأدوية العامة (Generic) التي تستخدم الواجهة المدمجة Array<T>:

\n\n
let fruits: Array<string> = ['apple', 'banana', 'cherry'];\nlet matrix: Array<Array<number>> = [[1, 2], [3, 4]];
\n\n

تبدو أكثر "أكاديمية"، لكنها توفر مرونة أكبر في السيناريوهات المعقدة.

\n\n

أفضل 5 أخطاء يرتكبها حتى المطورون ذوو الخبرة

\n\n

الخطأ رقم 1: الثقة العمياء في الإكمال التلقائي لبيئة التطوير

\n\n

قد تقترح بيئة التطوير الخاصة بك كلا الخيارين. لكن هذا لا يعني أنهما قابلان للتبادل في كل مكان. لننظر إلى مثال مع أنواع الاتحاد (union types):

\n\n
// هذا ممكن\ntype Status = 'active' | 'inactive';\nconst statuses1: Status[] = ['active', 'inactive'];\n\n// أما هكذا - خطأ نحوي!\n// const statuses2: Array<'active' | 'inactive'> = ['active', 'inactive']; \n// ❌ خطأ: ';' متوقع\n\n// الخيار الصحيح مع الأدوية العامة:\nconst statuses3: Array<Status> = ['active', 'inactive'];
\n\n

الخلاصة: داخل Array<> لا يمكن استخدام أنواع الاتحاد المعقدة مباشرة. قم أولاً باستخراجها في نوع منفصل.

\n\n

الخطأ رقم 2: الخلط مع المصفوفات غير القابلة للتعديل (readonly)

\n\n

عندما تحتاج إلى جعل المصفوفة غير قابلة للتغيير، تتصرف الصياغتان بشكل مختلف:

\n\n
// ✅ صحيح مع Type[]\nconst readonlyFruits: readonly string[] = ['apple', 'banana'];\n// readonlyFruits.push('orange'); // ❌ خطأ: readonly\n\n// ❌ هكذا لن يعمل:\n// const wrong: readonly Array<string> = ['apple']; \n// خطأ: معدّل 'readonly' يمكن أن يظهر فقط على أنواع المصفوفات\n\n// ✅ صحيح مع Array<> - استخدم ReadonlyArray:\nconst correct: ReadonlyArray<string> = ['apple', 'banana'];
\n\n

الخلاصة: للمصفوفات غير القابلة للتعديل، استخدم readonly Type[] أو ReadonlyArray<Type>. لا يمكن خلط readonly مع Array<>.

\n\n

الخطأ رقم 3: مشاكل مع المصفوفات متعددة المستويات

\n\n

عندما تحتوي المصفوفة على مصفوفات أخرى، تصبح صياغة Array<> ضخمة:

\n\n
// مقروءة وواضحة\nconst grid1: number[][] = [[1, 2], [3, 4]];\n\n// بالفعل أصعب في القراءة\nconst grid2: Array<Array<number>> = [[1, 2], [3, 4]];\n\n// وماذا لو كان هناك ثلاثة مستويات؟ كابوس:\nconst cube: Array<Array<Array<number>>> = [[[1]]]; // 🤯\n\n// مع Type[] الأمر أبسط:\nconst cube2: number[][][] = [[[1]]];
\n\n

الخلاصة: للمصفوفات ذات التداخل أكثر من مستويين، استخدم Type[][]. زملاؤك سيشكرونك.

\n\n

الخطأ رقم 4: تجاهل سياق الاستخدام

\n\n

في بعض الأطر (Angular, React) والمكتبات، هناك نمط معين متبع. مخالفة الاتفاقية قد تسبب ارتباكًا:

\n\n
// Angular غالبًا ما يستخدم                

المدونات

توصيات الكتب