العربية

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

TypeScript Interface مقابل Type: أفضل ممارسات التصريح للمطورين العالميين

تايب سكريبت (TypeScript)، وهي مجموعة شاملة من جافا سكريبت (JavaScript)، تُمكّن المطورين في جميع أنحاء العالم من بناء تطبيقات قوية وقابلة للتوسع من خلال الكتابة الثابتة (static typing). هناك نوعان أساسيان لتعريف الأنواع هما الواجهات (Interfaces) والأنواع (Types). على الرغم من تشابههما، فإن فهم الفروق الدقيقة بينهما وحالات الاستخدام المناسبة أمر حاسم لكتابة كود نظيف وقابل للصيانة وفعال. سيتعمق هذا الدليل الشامل في الاختلافات بين واجهات وأنواع تايب سكريبت، مستكشفًا أفضل الممارسات للاستفادة منها بفعالية في مشاريعك.

فهم واجهات تايب سكريبت (Interfaces)

الواجهة (Interface) في تايب سكريبت هي طريقة قوية لتعريف عقد (contract) لكائن ما. فهي تحدد شكل الكائن، وتعين الخصائص التي يجب أن يمتلكها، وأنواع بياناتها، واختياريًا، أي دوال (methods) يجب أن ينفذها. تصف الواجهات بشكل أساسي بنية الكائنات.

صيغة الواجهة ومثال عليها

صيغة تعريف الواجهة بسيطة ومباشرة:


interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

const user: User = {
  id: 123,
  name: "Alice Smith",
  email: "alice.smith@example.com",
  isActive: true,
};

في هذا المثال، تحدد الواجهة User بنية كائن المستخدم. أي كائن يتم إسناده إلى المتغير user يجب أن يلتزم بهذه البنية؛ وإلا، سيُصدر مترجم تايب سكريبت خطأ.

الميزات الرئيسية للواجهات

مثال على دمج التصريحات


interface Window {
  title: string;
}

interface Window {
  height: number;
  width: number;
}

const myWindow: Window = {
  title: "My Application",
  height: 800,
  width: 600,
};

هنا، تم التصريح عن الواجهة Window مرتين. يدمج تايب سكريبت هذين التصريحين، مما ينشئ فعليًا واجهة تحتوي على الخصائص title وheight وwidth.

استكشاف أنواع تايب سكريبت (Types)

يوفر النوع (Type) في تايب سكريبت طريقة لتعريف شكل البيانات. على عكس الواجهات، فإن الأنواع أكثر تنوعًا ويمكن أن تمثل نطاقًا أوسع من هياكل البيانات، بما في ذلك الأنواع الأولية (primitive types)، والاتحادات (unions)، والتقاطعات (intersections)، والصفوف (tuples).

صيغة النوع ومثال عليه

صيغة تعريف اسم مستعار للنوع (type alias) هي كما يلي:


type Point = {
  x: number;
  y: number;
};

const origin: Point = {
  x: 0,
  y: 0,
};

في هذا المثال، يحدد النوع Point بنية كائن نقطة بإحداثيات x وy.

الميزات الرئيسية للأنواع

مثال على نوع الاتحاد


type Result = {
  success: true;
  data: any;
} | {
  success: false;
  error: string;
};

const successResult: Result = {
  success: true,
  data: { message: "Operation successful!" },
};

const errorResult: Result = {
  success: false,
  error: "An error occurred.",
};

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

مثال على نوع التقاطع


type Person = {
  name: string;
  age: number;
};

type Employee = {
  employeeId: string;
  department: string;
};

type EmployeePerson = Person & Employee;

const employee: EmployeePerson = {
  name: "Bob Johnson",
  age: 35,
  employeeId: "EMP123",
  department: "Engineering",
};

النوع EmployeePerson هو نوع تقاطع، يجمع بين خصائص كل من Person وEmployee. يتيح لك هذا إنشاء أنواع جديدة من خلال دمج الأنواع الموجودة.

الفروقات الرئيسية: Interface مقابل Type

بينما تخدم كل من الواجهات والأنواع غرض تعريف هياكل البيانات في تايب سكريبت، هناك فروقات رئيسية تؤثر على وقت استخدام أحدهما على الآخر:

  1. دمج التصريحات: تدعم الواجهات دمج التصريحات، بينما لا تدعمها الأنواع. إذا كنت بحاجة إلى توسيع تعريف نوع عبر ملفات أو وحدات متعددة، فإن الواجهات هي الخيار المفضل عمومًا.
  2. أنواع الاتحاد: يمكن للأنواع أن تمثل أنواع الاتحاد، بينما لا يمكن للواجهات تعريف الاتحادات بشكل مباشر. إذا كنت بحاجة إلى تعريف نوع يمكن أن يكون واحدًا من عدة أنواع مختلفة، فاستخدم اسمًا مستعارًا للنوع (type alias).
  3. أنواع التقاطع: يمكن للأنواع إنشاء أنواع تقاطع باستخدام العامل &. يمكن للواجهات أن ترث من واجهات أخرى، مما يحقق تأثيرًا مشابهًا، لكن أنواع التقاطع توفر مرونة أكبر.
  4. الأنواع الأولية: يمكن للأنواع أن تمثل مباشرة الأنواع الأولية (string, number, boolean)، بينما تم تصميم الواجهات بشكل أساسي لتعريف أشكال الكائنات.
  5. رسائل الخطأ: يجد بعض المطورين أن الواجهات تقدم رسائل خطأ أوضح قليلاً مقارنة بالأنواع، خاصة عند التعامل مع هياكل أنواع معقدة.

أفضل الممارسات: الاختيار بين الواجهة والنوع

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

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

دعنا نأخذ بعض الأمثلة العملية لتوضيح كيفية استخدام الواجهات والأنواع في تطبيق عالمي:

1. إدارة ملفات تعريف المستخدمين (التدويل)

لنفترض أنك تبني نظامًا لإدارة ملفات تعريف المستخدمين يدعم لغات متعددة. يمكنك استخدام الواجهات لتعريف بنية ملفات تعريف المستخدمين والأنواع لتمثيل رموز اللغات المختلفة:


interface UserProfile {
  id: number;
  name: string;
  email: string;
  preferredLanguage: LanguageCode;
  address: Address;
}

interface Address {
    street: string;
    city: string;
    country: string;
    postalCode: string;
}

type LanguageCode = "en" | "fr" | "es" | "de" | "zh"; // أمثلة لرموز اللغات

const userProfile: UserProfile = {
  id: 1,
  name: "John Doe",
  email: "john.doe@example.com",
  preferredLanguage: "en",
  address: { street: "123 Main St", city: "Anytown", country: "USA", postalCode: "12345" }
};

هنا، تحدد الواجهة UserProfile بنية ملف تعريف المستخدم، بما في ذلك لغته المفضلة. النوع LanguageCode هو نوع اتحاد يمثل اللغات المدعومة. وتحدد الواجهة Address تنسيق العنوان، بافتراض وجود تنسيق عالمي عام.

2. تحويل العملات (العولمة)

فكر في تطبيق لتحويل العملات يحتاج إلى التعامل مع عملات وأسعار صرف مختلفة. يمكنك استخدام الواجهات لتعريف بنية كائنات العملة والأنواع لتمثيل رموز العملات:


interface Currency {
  code: CurrencyCode;
  name: string;
  symbol: string;
}

interface ExchangeRate {
  baseCurrency: CurrencyCode;
  targetCurrency: CurrencyCode;
  rate: number;
}


type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CAD"; // أمثلة لرموز العملات

const usd: Currency = {
  code: "USD",
  name: "United States Dollar",
  symbol: "$",
};

const exchangeRate: ExchangeRate = {
  baseCurrency: "USD",
  targetCurrency: "EUR",
  rate: 0.85,
};

تحدد الواجهة Currency بنية كائن العملة، بما في ذلك رمزها واسمها ورمزها. النوع CurrencyCode هو نوع اتحاد يمثل رموز العملات المدعومة. تُستخدم الواجهة ExchangeRate لتمثيل أسعار التحويل بين العملات المختلفة.

3. التحقق من صحة البيانات (التنسيق الدولي)

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


type PhoneNumber = {
  countryCode: string;
  number: string;
  isValid: boolean; // أضف قيمة منطقية لتمثيل البيانات الصالحة/غير الصالحة.
};

interface Contact {
   name: string;
   phoneNumber: PhoneNumber;
   email: string;
}


function validatePhoneNumber(phoneNumber: string, countryCode: string): PhoneNumber {
  // منطق التحقق بناءً على رمز البلد (على سبيل المثال، باستخدام مكتبة مثل libphonenumber-js)
  // ... التنفيذ هنا للتحقق من الرقم.
  const isValid = true; //قيمة مؤقتة

  return { countryCode, number: phoneNumber, isValid };
}

const contact: Contact = {
    name: "Jane Doe",
    phoneNumber: validatePhoneNumber("555-123-4567", "US"), //مثال
    email: "jane.doe@email.com",
};


console.log(contact.phoneNumber.isValid); //إخراج نتيجة التحقق.

الخلاصة: إتقان تصريحات تايب سكريبت

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

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