TypeScript📅 2026-10-03⏱ 9 دقائق قراءة📘 مقال 4 من 10

الواجهات في TypeScript — دليل شامل Interfaces 2026

دليل عملي مفصل للواجهات في TypeScript — تعريف Interfaces، extends، implements، الفرق بينها وبين type، مع تمارين وحلول

في المقال السابق، تعلمت الأنواع الأساسية في TypeScript. الآن سنتعمق في الواجهات (Interfaces) — وهي إحدى أقوى ميزات TypeScript لتعريف هياكل البيانات.

في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم الواجهات، والفرق بينها وبين type، وكيفية استخدامها في مشاريعك، مع تمارين وحلول.

ما هي الواجهة (Interface)؟

الواجهة هي عقد (Contract) يحدد شكل الكائن — ما الخصائص التي يجب أن يحتويها، وما أنواعها.

تشبيه بسيط: تخيل أن الواجهة هي "قالب" أو "مخطط" لبناء منزل. أي منزل يُبنى من هذا القالب يجب أن يحتوي على: غرفة نوم، مطبخ، حمام.

مثال:

interface User {
  name: string;
  age: number;
  email: string;
}

const user: User = {
  name: "أحمد",
  age: 25,
  email: "[email protected]",
};

شرح:

  • interface User: تعريف واجهة باسم User.
  • { name: string; ... }: الخصائص المطلوبة.
  • : User: المتغير user يجب أن يطابق واجهة User.

⚠️ مهم: إذا نسيت خاصية أو كتبتها بنوع خاطئ، TypeScript ستعطي خطأ:

const user: User = {
  name: "أحمد",
  age: "25",  // ❌ خطأ: يجب أن يكون number
  // ❌ خطأ: email مفقود
};

لماذا نحتاج الواجهات؟

  • الوضوح: الكود يوثق نفسه.
  • الأمان: تكتشف الأخطاء قبل التشغيل.
  • إعادة الاستخدام: عرّف الواجهة مرة، استخدمها في أماكن كثيرة.
  • الأدوات: إكمال تلقائي (IntelliSense) أفضل.
  • التعاون: الفريق يفهم بنية البيانات.

الخصائص الاختيارية (Optional Properties)

استخدم ? لجعل خاصية اختيارية:

interface User {
  name: string;
  age: number;
  email?: string;  // اختياري
}

const user1: User = {
  name: "أحمد",
  age: 25,
};  // ✅ صحيح

const user2: User = {
  name: "محمد",
  age: 30,
  email: "[email protected]",
};  // ✅ صحيح

خصائص القراءة فقط (Readonly)

استخدم readonly لمنع التعديل بعد الإنشاء:

interface Config {
  readonly apiKey: string;
  readonly baseUrl: string;
  timeout: number;  // قابل للتعديل
}

const config: Config = {
  apiKey: "abc123",
  baseUrl: "https://api.example.com",
  timeout: 5000,
};

config.timeout = 10000;  // ✅ مسموح
// config.apiKey = "new-key";  // ❌ خطأ

طرق (Methods) في الواجهات

يمكنك تعريف دوال داخل الواجهة:

interface Calculator {
  add(a: number, b: number): number;
  subtract(a: number, b: number): number;
}

const calc: Calculator = {
  add(a, b) {
    return a + b;
  },
  subtract(a, b) {
    return a - b;
  },
};

console.log(calc.add(5, 3));       // 8
console.log(calc.subtract(5, 3));  // 2

الفهارس (Index Signatures)

إذا كنت لا تعرف أسماء الخصائص مسبقاً:

interface StringMap {
  [key: string]: string;
}

const colors: StringMap = {
  red: "#FF0000",
  green: "#00FF00",
  blue: "#0000FF",
};

console.log(colors.red);   // #FF0000
console.log(colors["green"]);  // #00FF00

مثال عملي: قاموس (Dictionary):

interface Dictionary {
  [key: string]: number;
}

const ages: Dictionary = {
  ahmed: 25,
  mohamed: 30,
  ali: 22,
};

console.log(ages.ahmed);  // 25

توسيع الواجهات (Interface Extension)

يمكنك بناء واجهة على واجهة أخرى باستخدام extends:

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

interface Employee extends Person {
  company: string;
  salary: number;
}

const emp: Employee = {
  name: "أحمد",
  age: 25,
  company: "Google",
  salary: 50000,
};

توسيع متعدد:

interface A {
  a: string;
}

interface B {
  b: string;
}

interface C extends A, B {
  c: string;
}

const obj: C = {
  a: "a",
  b: "b",
  c: "c",
};

تنفيذ الواجهات (implements)

الفئات (Classes) يمكنها تنفيذ الواجهات:

interface Animal {
  name: string;
  makeSound(): void;
}

class Dog implements Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  makeSound(): void {
    console.log(`${this.name} يقول: هاو هاو!`);
  }
}

const dog = new Dog("روكي");
dog.makeSound();  // روكي يقول: هاو هاو!

الفرق بين interface و type

هذا سؤال شائع جداً. دعنا نوضح:

المعيارinterfacetype
تعريف الكائنات✅ ممتاز✅ ممتاز
Union Types❌ لا يدعم✅ يدعم
Intersection✅ عبر extends✅ عبر &
إعادة التعريف (Declaration Merging)✅ يدعم❌ لا يدعم
implements في Classes✅ يدعم✅ يدعم
Tuple❌ لا يدعم✅ يدعم

متى تستخدم interface؟

  • لتعريف شكل الكائنات (Objects).
  • للفئات (Classes) التي تنفذ الواجهة.
  • عندما تحتاج إلى إعادة تعريف (Declaration Merging).

متى تستخدم type؟

  • لـ Union Types (string | number).
  • لـ Tuple ([string, number]).
  • للأنواع البدائية (type ID = string | number).
  • للأنواع المعقدة (Conditional, Mapped, ...).

مثال مقارن:

// interface
interface User {
  name: string;
  age: number;
}

// type
type User = {
  name: string;
  age: number;
};

كلاهما يعمل بنفس الطريقة لتحديد شكل الكائن.

لكن:

// type يدعم Union
type Status = "pending" | "approved" | "rejected";

// interface لا يدعم Union
// interface Status = "pending" | "approved";  // ❌ خطأ

إعادة التعريف (Declaration Merging):

// interface: يمكن إعادة تعريفها
interface User {
  name: string;
}

interface User {
  age: number;
}

// النتيجة: User له name و age

const user: User = {
  name: "أحمد",
  age: 25,
};

// type: لا يمكن إعادة تعريفها
type Person = { name: string };
// type Person = { age: number };  // ❌ خطأ

الواجهات للدوال (Call Signatures)

يمكنك تعريف واجهة تمثل دالة:

interface GreetFunction {
  (name: string): string;
}

const greet: GreetFunction = (name) => `مرحباً ${name}`;

console.log(greet("أحمد"));  // مرحباً أحمد

الواجهات للفئات (Construct Signatures)

interface PersonConstructor {
  new (name: string, age: number): Person;
}

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

class PersonImpl implements Person {
  constructor(public name: string, public age: number) {}
}

const PersonClass: PersonConstructor = PersonImpl;
const person = new PersonClass("أحمد", 25);

تمارين عملية

تمرين 1: واجهة مستخدم

عرّف واجهة User تحتوي على:

  • id (number)
  • name (string)
  • email (string)
  • isActive (boolean)

الحل:

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

const user: User = {
  id: 1,
  name: "أحمد",
  email: "[email protected]",
  isActive: true,
};

تمرين 2: خصائص اختيارية

عرّف واجهة Product تحتوي على:

  • name (string)
  • price (number)
  • description (string, اختياري)
  • discount (number, اختياري)

الحل:

interface Product {
  name: string;
  price: number;
  description?: string;
  discount?: number;
}

const product1: Product = {
  name: "لابتوب",
  price: 5000,
};

const product2: Product = {
  name: "هاتف",
  price: 2000,
  description: "هاتف ذكي",
  discount: 10,
};

تمرين 3: توسيع الواجهات

عرّف Person، ثم Student يرث منها.

الحل:

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

interface Student extends Person {
  studentId: string;
  major: string;
}

const student: Student = {
  name: "أحمد",
  age: 20,
  studentId: "S12345",
  major: "علوم حاسب",
};

تمرين 4: دالة في واجهة

عرّف واجهة Shape لها دالة area().

الحل:

interface Shape {
  area(): number;
}

const circle: Shape = {
  area() {
    return Math.PI * 5 * 5;
  },
};

console.log(circle.area());  // 78.5398...

تمرين 5: قاموس

عرّف Dictionary يخزن string -> number.

الحل:

interface Dictionary {
  [key: string]: number;
}

const scores: Dictionary = {
  ahmed: 95,
  mohamed: 88,
  ali: 92,
};

console.log(scores.ahmed);  // 95

تمرين 6: implements

أنشئ واجهة Vehicle وفئة Car تنفذها.

الحل:

interface Vehicle {
  brand: string;
  speed: number;
  accelerate(): void;
}

class Car implements Vehicle {
  brand: string;
  speed: number;

  constructor(brand: string, speed: number) {
    this.brand = brand;
    this.speed = speed;
  }

  accelerate(): void {
    this.speed += 10;
    console.log(`${this.brand} تسارع إلى ${this.speed} كم/س`);
  }
}

const car = new Car("تويوتا", 100);
car.accelerate();  // تويوتا تسارع إلى 110 كم/س

تمرين 7: واجهة API Response

عرّف واجهة تمثل استجابة API.

الحل:

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message?: string;
}

interface User {
  id: number;
  name: string;
}

const response: ApiResponse<User> = {
  success: true,
  data: { id: 1, name: "أحمد" },
  message: "تم بنجاح",
};

⚠️ ملاحظة: هذا مثال متقدم قليلاً (Generics). سنتعلمه في مقال لاحق.

تمرين 8: الفرق بين interface و type

عرّف نوع Status باستخدام type، ونوع User باستخدام interface.

الحل:

type Status = "active" | "inactive" | "pending";

interface User {
  id: number;
  name: string;
  status: Status;
}

const user: User = {
  id: 1,
  name: "أحمد",
  status: "active",
};

حل المشاكل الشائعة

🔴 المشكلة 1: Property 'X' is missing

السبب: نسيت خاصية مطلوبة.

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

const user: User = {
  name: "أحمد",
  // ❌ age مفقود
};

الحل: أضف الخاصية المفقودة، أو اجعلها اختيارية ?.

🔴 المشكلة 2: Type 'X' is not assignable to type 'Y'

السبب: نوع خاصية مختلف.

interface User {
  age: number;
}

const user: User = {
  age: "25",  // ❌ يجب أن يكون number
};

الحل: استخدم النوع الصحيح.

🔴 المشكلة 3: Cannot assign to 'X' because it is a read-only property

السبب: حاولت تعديل خاصية readonly.

الحل: احذف readonly إذا كنت تريد التعديل، أو لا تعدّل.

🔴 المشكلة 4: Interface 'X' incorrectly extends interface 'Y'

السبب: توسيع واجهة بنوع غير متوافق.

الحل: تأكد من توافق الأنواع في الواجهة الفرعية.

جدول الأوامر الأساسية

الأمرالوظيفة
interface X { }تعريف واجهة
property?: typeخاصية اختيارية
readonly propertyخاصية للقراءة فقط
interface X extends Yتوسيع واجهة
class X implements Yتنفيذ واجهة
[key: string]: typeفهرس ديناميكي

قائمة تحقق نهائية

المهمةالحالة
فهم الواجهات وكيفية تعريفها⬜
استخدام الخصائص الاختيارية (?)⬜
استخدام readonly⬜
تعريف دوال في الواجهات⬜
توسيع الواجهات (extends)⬜
تنفيذ الواجهات (implements)⬜
فهم الفرق بين interface و type⬜
حل التمارين الثمانية⬜

ماذا بعد هذا المقال؟

الآن بعد أن أتقنت الواجهات، أنت جاهز للمقال التالي:

  1. الدوال مع الأنواع — تعمق في أنواع الدوال.
  2. الفئات (Classes) — البرمجة كائنية التوجه.
  3. الأدوية (Generics) — الأنواع العامة.

الخلاصة

في هذا المقال، تعلمت:

  • ✅ ما هي الواجهات ولماذا نحتاجها.
  • ✅ تعريف الواجهات والخصائص الاختيارية.
  • ✅ readonly و Index Signatures.
  • ✅ الطرق (Methods) في الواجهات.
  • ✅ توسيع الواجهات (extends).
  • ✅ تنفيذ الواجهات (implements).
  • ✅ الفرق بين interface و type.

تذكر: الواجهات هي أساس المشاريع الكبيرة في TypeScript. أتقنها جيداً.

هل أتقنت الواجهات؟ شاركنا في التعليقات!

📚 مقالات ذات صلة

TypeScript

مشروع Node.js مع TypeScript — API كامل 2026

مشروع عملي لبناء API كامل بـ Node.js و Express و TypeScript — خطوة بخطوة مع الكود الكامل والشرح

TypeScript

مشروع React مع TypeScript — تطبيق مهام كامل 2026

مشروع عملي لبناء تطبيق مهام (Todo App) بـ React و TypeScript — خطوة بخطوة مع الكود الكامل والشرح

TypeScript

الأنواع المتقدمة في TypeScript — دليل شامل 2026

دليل عملي مفصل للأنواع المتقدمة في TypeScript — Union, Intersection, Conditional, Mapped, Template Literal، مع تمارين وحلول