نوع المصفوفة في TypeScript هو نوع العنصر متبوعًا بـ []: string[] مصفوفة نصوص، وnumber[] مصفوفة أرقام. والكتابة العامة Array<string> هي النوع نفسه. بعد تحديد نوع المصفوفة، يكون لكل عنصر تضيفه وكل عنصر تقرؤه ذلك النوع.
سطر @ts-expect-error خطأ ترجمة (TS2345). هنا يُعلَّم على أنه متوقع حتى يعمل المثال، ولأن الأنواع تُمحى، يُضاف 42 فعلًا وقت التشغيل: الناتج يظهر ذلك.
string[] مقابل Array<string>
| الكتابة | تساوي | ملاحظات |
|---|---|---|
string[] | Array<string> | الكتابة الشائعة. |
(string | number)[] | Array<string | number> | الأقواس ضرورية: string | number[] تعني «نص، أو مصفوفة أرقام». |
readonly string[] | ReadonlyArray<string> | لا push ولا pop ولا sort ولا إسناد بالفهرس. |
User[] | Array<User> | مصفوفات الكائنات تستخدم نوع الكائن. |
string[][] | Array<Array<string>> | مصفوفة ثنائية الأبعاد (شبكة). |
اختر أسلوبًا واحدًا لقاعدة الكود. القاعدة array-type في typescript-eslint تفضّل T[] افتراضيًا.
مصفوفات الكائنات
صِف العنصر بـ type alias أو interface، ثم استخدم Type[]. كل ما يُقرأ من المصفوفة يُفحص مقابل ذلك الشكل.
الكائن الحرفي الذي يُضاف إلى users يجب أن يطابق User تمامًا: غياب admin أو خطأ إملائي في اسم خاصية خطأ ترجمة.
أنواع map وfilter وreduce وfind
دوال المصفوفات عامة (generic)، لذلك تحمل نتائجها أنواعًا. ما تفعله كل دالة وقت التشغيل مشروح في صفحة دوال المصفوفات في JavaScript؛ والأنواع هي ما تضيفه TypeScript:
| الدالة | نوع الناتج على T[] |
|---|---|
map(fn) | U[]، حيث U ما تعيده fn |
filter(fn) | T[] (أو نوع أضيق، انظر أدناه) |
find(fn) | T | undefined |
findIndex(fn) وindexOf(x) | number (-1 عند الغياب) |
some(fn) وevery(fn) وincludes(x) | boolean |
reduce(fn, init) | نوع init (أو وسيط النوع، reduce<R>(...)) |
at(i) | T | undefined |
join(sep) | string |
يعمل المثال الأخير لأن TypeScript (منذ 5.5) تستنتج أن (n) => n !== undefined هو type predicate، فتعيد filter النوع number[] بدل (number | undefined)[]. وللفحوص التي لا تستطيع استنتاجها، اكتب الـ predicate بنفسك: filter((x): x is User => x !== null).
مصفوفات تحمل أكثر من نوع
نوع عنصر من union يسمح بالخلط. أما union من أنواع مصفوفات فلا:
عندما تكون للمواضع أنواع ثابتة، مثل زوج [name, age]، استخدم tuple بدلًا من ذلك: يعرف [string, number] أن الفهرس 0 نص والفهرس 1 رقم، بينما لا يعرف (string | number)[] ذلك.
المصفوفات للقراءة فقط
يحذف readonly T[] كل دالة تعدّل المصفوفة. استخدمه للمعاملات التي يجب ألا تغيّرها الدالة، وللثوابت.
index.ts(3,12): error TS2339: Property 'push' does not exist on type 'readonly number[]'.
احذف سطر push فيطبع المثال 4. يمكن دائمًا تمرير number[] القابلة للتعديل حيث يُتوقع readonly number[]، لذلك لا تكلف معاملات readonly المستدعين شيئًا. الفحص وقت الترجمة فقط: وقت التشغيل هي مصفوفة عادية. ولترتيب مصفوفة للقراءة فقط، رتّب نسخة منها: [...values].sort().
مشكلة includes مع المصفوفات الحرفية
يحوّل as const المصفوفة إلى tuple للقراءة فقط من أنواع حرفية. هذا مفيد لقائمة من القيم المسموحة، لكن includes فيها لا يقبل عندئذ إلا تلك القيم الحرفية:
وضع الفحص داخل type guard (value is Color) يعني أن التوسيع يحدث مرة واحدة، ويحصل المستدعون على قيمة مضيَّقة.
الفهرسة والمصفوفات الفارغة
قراءة arr[i] تعطي النوع T، حتى عندما يكون i خارج النطاق وتكون القيمة وقت التشغيل undefined. أما at(i) فنوعها T | undefined، وخيار المترجم noUncheckedIndexedAccess يجعل الفهرسة العادية تعيد T | undefined أيضًا.
كان queue[0].toUpperCase() سيُترجم ثم يرمي TypeError وقت التشغيل. فضّل at() أو فحص الطول أو noUncheckedIndexedAccess عندما قد يكون الفهرس غير موجود.
الأسئلة الشائعة
كيف أعرّف نوع مصفوفة في TypeScript؟
اكتب نوع العنصر متبوعًا بـ []: let names: string[] = ["a", "b"]. والصيغة العامة Array<string> تعني الشيء نفسه تمامًا. ولمصفوفة كائنات، استخدم نوع كائن أو interface كنوع للعنصر: User[].
ما الفرق بين string[] و Array<string>؟
لا فرق: إنهما طريقتان لكتابة النوع نفسه. string[] أكثر شيوعًا. والصيغة العامة أسهل قراءة مع أنواع العناصر المعقدة، وبالمثل فإن readonly string[] وReadonlyArray<string> هما النوع نفسه للمصفوفات للقراءة فقط.
لماذا تعيد find القيمة undefined في TypeScript؟
تعيد array.find() النوع T | undefined لأن أي عنصر قد لا يطابق. تحت strict يجب أن تعالج حالة undefined، بفحص if أو optional chaining (found?.name) أو قيمة بديلة (found ?? fallback)، قبل استخدام الناتج.
كيف أحدد نوع مصفوفة تحمل عدة أنواع في TypeScript؟
استخدم union كنوع للعنصر بين قوسين: (string | number)[] مصفوفة كل عنصر فيها نص أو رقم. وهذا يختلف عن string[] | number[]، التي تكون إما مصفوفة نصوص فقط أو مصفوفة أرقام فقط. ولترتيب ثابت للأنواع، مثل [string, number]، استخدم tuple.
لماذا تعطي includes خطأ مع مصفوفة as const؟
as const؟المصفوفة الحرفية للقراءة فقط، مثل ["red", "green"] as const، لديها includes(searchElement: "red" | "green")، لذلك تمرير string عادي هو الخطأ TS2345. وسّع نوع المصفوفة من أجل الفحص، (COLORS as readonly string[]).includes(input)، ويفضل أن يكون ذلك داخل type guard يضيّق input إلى union الحرفي.