Generics في TypeScript: دليل كامل للمبتدئين

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

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

ابدأ الدورة

Generics في TypeScript: لماذا هي ضرورية وكيفية استخدامها



TypeScript هي أداة قوية تضيف كتابة الأنواع الثابتة إلى JavaScript. ومع ذلك، إذا كنت بدأت للتو في تعلم TypeScript، فقد تواجه موقفًا حيث تضطر إلى كتابة نفس الكود لأنواع بيانات مختلفة. هنا تأتي Generics (الأنواع العامة أو الأدوية العامة) للإنقاذ. في هذه المقالة، سنشرح ما هي Generics، ولماذا هي ضرورية، وكيفية استخدامها عمليًا.



ما هي Generics ولماذا هي مهمة؟



Generics هي آلية في TypeScript تسمح لك بإنشاء مكونات (دوال، كلاسات، واجهات) تعمل مع أنواع بيانات مختلفة، بدلاً من نوع واحد محدد. تخيل أنك تكتب دالة يجب أن تعمل مع الأرقام والنصوص والمصفوفات. بدون الأدوية العامة، سيتعين عليك إما استخدام النوع any (مما يقتل جوهر TypeScript) أو إنشاء نسخ متعددة من نفس الدالة.



المزايا الرئيسية لـ Generics:

  • أمان الأنواع — تحافظ على كتابة الأنواع الصارمة، لكن الكود يظل مرنًا.
  • إعادة استخدام الكود — يمكن لدالة أو كلاس واحد العمل مع أنواع مختلفة.
  • قابلية القراءة — يصبح الكود أكثر وضوحًا وموثقًا ذاتيًا.


الصيغة الأساسية لـ Generics



لنبدأ بأبسط مثال. لنفترض أننا بحاجة إلى دالة تعيد الوسيط الذي تم تمريره إليها. بدون Generics، سنكتب هكذا:



function identity(arg: number): number {    return arg;}


ولكن ماذا لو أردنا تمرير نص؟ سيتعين علينا إنشاء دالة جديدة. باستخدام Generics، نفعل هكذا:



function identity<T>(arg: T): T {    return arg;}

// الاستخدام:let output1 = identity<string>("مرحبًا");let output2 = identity<number>(42);let output3 = identity<boolean>(true);


هنا <T> هو معامل النوع (أو متغير النوع). عندما نستدعي الدالة، يقوم TypeScript تلقائيًا بتعيين النوع المناسب. يمكنك استخدام أي حرف: T، U، V أو حتى أسماء ذات معنى مثل Type.



بالمناسبة، يمكن لـ TypeScript استنتاج النوع بنفسه، لذلك غالبًا ما يمكنك الكتابة دون تحديد صريح:



let output = identity("مرحبًا"); // TypeScript سيفهم أن T = string


العمل مع المصفوفات والأنواع المتعددة



أحد أكثر استخدامات Generics شيوعًا هو العمل مع المصفوفات. لنفترض أننا نريد كتابة دالة تأخذ مصفوفة وتعيد العنصر الأول:



function getFirstElement<T>(arr: T[]): T | undefined {    return arr[0];}

const numbers = [1, 2, 3];const firstNumber = getFirstElement(numbers); // النوع number | undefined

const strings = ["a", "b", "c"];const firstString = getFirstElement(strings); // النوع string | undefined


لاحظ: استخدمنا T[] — وهو نفس Array<T>. ماذا لو كانت الدالة تأخذ نوعين مختلفين؟ بسهولة!



function merge<T, U>(obj1: T, obj2: U): T & U {    return { ...obj1, ...obj2 };}

const result = merge({ name: "آنا" }, { age: 25 });// result له النوع { name: string; } & { age: number; }// في الواقع: { name: string; age: number; }


قيود Generics (Constraints)



أحيانًا تحتاج أن تعمل الأدوية العامة ليس مع أي نوع، بل فقط مع تلك التي لها خصائص معينة. لهذا، تُستخدم القيود باستخدام الكلمة المفتاحية extends.



على سبيل المثال، نريد كتابة دالة تحصل على طول الكائن. من الواضح أنه ليست كل الأنواع لها خاصية length. دعنا نتحقق من ذلك:



function getLength<T extends { length: number                

المدونات

توصيات الكتب