شرح أنواع TypeScript المتقدمة مع الأمثلة

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

أنواع الاتحاد

تسمح أنواع الاتحاد للمتغير بأن يكون أحد أنواع متعددة. يمكن أن يكون هذا مفيدًا عندما تكون القيمة من أنواع متعددة ولكن يجب التعامل معها بشكل مناسب بناءً على نوعها الفعلي.

// Union type example

function formatValue(value: string | number): string {
  if (typeof value === 'string') {
    return `String: ${value}`;
  } else {
    return `Number: ${value.toFixed(2)}`;
  }
}

console.log(formatValue("Hello"));
console.log(formatValue(123.456));

في هذا المثال، تقبل الدالة `formatValue` إما سلسلة أو رقمًا وتقوم بتنسيق القيمة وفقًا لذلك.

أنواع التقاطعات

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

// Intersection type example

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

interface Contact {
  email: string;
  phone: string;
}

type Employee = Person & Contact;

const employee: Employee = {
  name: "John Doe",
  age: 30,
  email: "john.doe@example.com",
  phone: "123-456-7890"
};

console.log(employee);

هنا، يعتبر نوع "الموظف" تقاطعًا بين "الشخص" و"جهة الاتصال"، مما يعني أنه يحتوي على خصائص من كلتا الواجهتين.

أنواع حرفية

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

// Literal type example

type Direction = "up" | "down" | "left" | "right";

function move(direction: Direction): void {
  console.log(`Moving ${direction}`);
}

move("up");    // Valid
move("down");  // Valid
// move("side"); // Error: Argument of type '"side"' is not assignable to parameter of type 'Direction'.

يقتصر نوع `Direction` هنا على أربع قيم سلسلة محددة، مما يضمن إمكانية استخدام هذه الاتجاهات فقط في وظيفة `move`.

أنواع التوبل

تمثل أنواع العناصر المصفوفة مصفوفة تحتوي على عدد ثابت من العناصر حيث يمكن أن يكون لكل عنصر نوع مختلف. تعد العناصر المصفوفة مفيدة لتمثيل مجموعات ذات حجم ثابت من العناصر غير المتجانسة.

// Tuple type example

let user: [string, number] = ["Alice", 30];

console.log(user[0]); // "Alice"
console.log(user[1]); // 30

// user = [30, "Alice"]; // Error: Type 'number' is not assignable to type 'string'.

يتم تعريف مجموعة "المستخدم" بسلسلة متبوعة برقم، ويجب الحفاظ على هذا الهيكل.

أنواع الشرطية

تسمح الأنواع الشرطية بتحديد الأنواع بناءً على الشروط. وهي توفر طريقة لاختيار نوع أو آخر بناءً على شرط.

// Conditional type example

type IsString = T extends string ? "Yes" : "No";

type Test1 = IsString;  // "Yes"
type Test2 = IsString;  // "No"

في هذا المثال، يتحقق النوع `IsString` مما إذا كان النوع `T` عبارة عن سلسلة نصية. ويعيد ``Yes`` إذا كان كذلك و``No`` بخلاف ذلك.

أنواع مُخططة

تسمح الأنواع المرسومة بإنشاء أنواع جديدة عن طريق تحويل خصائص نوع موجود. وهذا مفيد لتعديل أو توسيع الأنواع الموجودة.

// Mapped type example

type ReadonlyPerson = {
  readonly [K in keyof Person]: Person[K];
};

const readonlyPerson: ReadonlyPerson = {
  name: "Alice",
  age: 30
};

// readonlyPerson.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.

يقوم النوع `ReadonlyPerson` بتحويل النوع `Person` عن طريق جعل جميع خصائصه للقراءة فقط.

خاتمة

توفر أنواع TypeScript المتقدمة أدوات قوية لتحديد وإدارة متطلبات الأنواع المعقدة. من خلال الاستفادة من أنواع الاتحاد والتقاطع والحرفية والثنائية والشرطية والمُعينة، يمكن للمطورين إنشاء تطبيقات أكثر قوة وقابلية للصيانة. إن فهم هذه الأنواع وتطبيقها بشكل فعال يمكن أن يعزز بشكل كبير من أمان النوع ومرونة كود TypeScript.