الدوال في TypeScript — دليل شامل Functions 2026
دليل عملي مفصل للدوال في TypeScript — أنواع المعاملات، القيم المرجعة، Overloads، Optional Parameters، مع تمارين وحلول
في المقال السابق، تعلمت الواجهات وكيفية تعريف هياكل البيانات. الآن سنتعمق في الدوال (Functions) — مع إضافة قوة TypeScript المتمثلة في الأنواع.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم الدوال في TypeScript، مع تمارين وحلول.
ما هي الدالة؟
الدالة هي كتلة من الكود لها اسم، تؤدي مهمة محددة، ويمكن استدعاؤها عدة مرات.
مثال بسيط:
function greet(name: string): string {
return `مرحباً ${name}!`;
}
console.log(greet("أحمد")); // مرحباً أحمد!
شرح:
function: كلمة مفتاحية لتعريف الدالة.greet: اسم الدالة.name: string: المعامل مع نوعه.: string: نوع القيمة المرجعة.return ...: القيمة التي ترجعها الدالة.
لماذا نستخدم الدوال؟
- إعادة الاستخدام: اكتب مرة، استخدم عدة مرات.
- التنظيم: قسم البرنامج إلى أجزاء صغيرة.
- سهولة الصيانة: عدّل في مكان واحد.
- الوضوح: الكود يصبح أسهل للقراءة.
- الاختبار: يمكن اختبار كل دالة على حدة.
أنواع الدوال في TypeScript
1. Function Declaration — التعريف التقليدي
function add(a: number, b: number): number {
return a + b;
}
console.log(add(5, 3)); // 8
ميزتها: يمكن استدعاؤها قبل تعريفها (Hoisting).
2. Function Expression — تعبير دالة
const add = function(a: number, b: number): number {
return a + b;
};
console.log(add(5, 3)); // 8
الفرق: لا يمكن استدعاؤها قبل التعريف.
3. Arrow Function — الدالة السهمية
const add = (a: number, b: number): number => {
return a + b;
};
// أو أقصر (إذا كان سطراً واحداً):
const add = (a: number, b: number): number => a + b;
ميزاتها:
- أقصر.
- لا تحتاج
function. - إذا كان السطر واحداً، يمكن حذف
{}وreturn.
4. دالة بدون معاملات
const greet = (): string => "مرحباً!";
console.log(greet()); // مرحباً!
5. دالة بدون قيمة مرجعة (void)
function logMessage(message: string): void {
console.log(message);
}
logMessage("مرحباً"); // مرحباً
أنواع المعاملات
1. المعاملات المطلوبة
function greet(name: string, age: number): string {
return `مرحباً ${name}، عمرك ${age}`;
}
console.log(greet("أحمد", 25));
2. المعاملات الاختيارية (Optional)
استخدم ? لجعل المعامل اختيارياً:
function greet(name: string, title?: string): string {
if (title) {
return `مرحباً ${title} ${name}`;
}
return `مرحباً ${name}`;
}
console.log(greet("أحمد")); // مرحباً أحمد
console.log(greet("أحمد", "دكتور")); // مرحباً دكتور أحمد
⚠️ مهم: المعاملات الاختيارية يجب أن تكون بعد المعاملات المطلوبة.
// ❌ خطأ:
function greet(title?: string, name: string) {}
// ✅ صحيح:
function greet(name: string, title?: string) {}
3. القيم الافتراضية (Default)
function greet(name: string = "زائر"): string {
return `مرحباً ${name}`;
}
console.log(greet()); // مرحباً زائر
console.log(greet("أحمد")); // مرحباً أحمد
4. المعاملات المتبقية (Rest Parameters)
function sum(...numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
console.log(sum()); // 0
أنواع القيم المرجعة
1. نوع محدد
function add(a: number, b: number): number {
return a + b;
}
2. void — لا قيمة
function log(message: string): void {
console.log(message);
}
3. never — لا يحدث أبداً
function throwError(message: string): never {
throw new Error(message);
}
4. Union — عدة أنواع
function parse(value: string): number | null {
const num = Number(value);
return isNaN(num) ? null : num;
}
console.log(parse("123")); // 123
console.log(parse("abc")); // null
5. Promise (للدوال غير المتزامنة)
async function fetchData(): Promise<string> {
return "بيانات";
}
نوع الدالة (Function Type)
يمكنك تعريف نوع للدالة:
type MathOperation = (a: number, b: number) => number;
const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;
const multiply: MathOperation = (a, b) => a * b;
الفائدة: يمكن استخدام نفس النوع لعدة دوال.
الدوال كمعاملات (Callbacks)
function processArray(
arr: number[],
callback: (item: number) => number
): number[] {
return arr.map(callback);
}
const doubled = processArray([1, 2, 3], (n) => n * 2);
console.log(doubled); // [2, 4, 6]
const squared = processArray([1, 2, 3], (n) => n * n);
console.log(squared); // [1, 4, 9]
الدوال المُرجَعة (Higher-Order Functions)
الدوال التي ترجع دوالاً:
function createMultiplier(factor: number): (n: number) => number {
return (n) => n * factor;
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
الدوال العامة (Overloads)
يمكن لدالة أن يكون لها عدة تواقيع:
function greet(name: string): string;
function greet(names: string[]): string;
function greet(value: string | string[]): string {
if (Array.isArray(value)) {
return `مرحباً ${value.join(", ")}`;
}
return `مرحباً ${value}`;
}
console.log(greet("أحمد")); // مرحباً أحمد
console.log(greet(["أحمد", "محمد"])); // مرحباً أحمد, محمد
متى تستخدمها؟ عندما تريد أن تتعامل الدالة مع أنواع مختلفة من المدخلات.
الدوال المجهولة (Anonymous Functions)
دالة بدون اسم، تُستخدم كقيمة:
const greet = function(name: string): string {
return `مرحباً ${name}`;
};
// أو كـ Arrow:
const greet2 = (name: string): string => `مرحباً ${name}`;
الدوال العودية (Recursion)
الدالة التي تستدعي نفسها:
function factorial(n: number): number {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
⚠️ تحذير: تأكد من وجود حالة توقف (base case)، وإلا ستحدث حلقة لا نهائية.
الدوال غير المتزامنة (Async/Await)
async function fetchUser(id: number): Promise<{ id: number; name: string }> {
// محاكاة طلب API
return { id, name: "أحمد" };
}
async function main() {
const user = await fetchUser(1);
console.log(user.name); // أحمد
}
Generics في الدوال
Generics تسمح للدالة بالعمل مع أنواع مختلفة:
function identity<T>(value: T): T {
return value;
}
console.log(identity<string>("أحمد")); // أحمد
console.log(identity<number>(25)); // 25
console.log(identity<boolean>(true)); // true
// TypeScript تستنتج النوع تلقائياً:
console.log(identity("أحمد")); // أحمد
تمارين عملية
تمرين 1: دالة الترحيب
اكتب دالة تأخذ اسماً وترجع "مرحباً [الاسم]".
الحل:
function greet(name: string): string {
return `مرحباً ${name}`;
}
console.log(greet("أحمد")); // مرحباً أحمد
تمرين 2: دالة المجموع
اكتب دالة تأخذ رقمين وترجع مجموعهما.
الحل:
const add = (a: number, b: number): number => a + b;
console.log(add(5, 3)); // 8
console.log(add(10, 20)); // 30
تمرين 3: دالة الأكبر
اكتب دالة تأخذ رقمين وترجع الأكبر.
الحل:
function max(a: number, b: number): number {
return a > b ? a : b;
}
console.log(max(5, 10)); // 10
console.log(max(20, 8)); // 20
تمرين 4: دالة الزوجي
اكتب دالة تتحقق إذا كان الرقم زوجياً.
الحل:
const isEven = (num: number): boolean => num % 2 === 0;
console.log(isEven(4)); // true
console.log(isEven(7)); // false
تمرين 5: دالة المساحة
اكتب دالة تحسب مساحة مستطيل.
الحل:
function area(width: number, height: number): number {
return width * height;
}
console.log(area(5, 10)); // 50
تمرين 6: دالة المتوسط
اكتب دالة تأخذ مصفوفة أرقام وترجع متوسطها.
الحل:
function average(numbers: number[]): number {
if (numbers.length === 0) return 0;
const sum = numbers.reduce((acc, n) => acc + n, 0);
return sum / numbers.length;
}
console.log(average([10, 20, 30, 40])); // 25
تمرين 7: دالة Rest Parameters
اكتب دالة تجمع أي عدد من الأرقام.
الحل:
function sum(...numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
تمرين 8: دالة Overload
اكتب دالة تستقبل string أو string[] وترجع ترحيباً مناسباً.
الحل:
function greet(name: string): string;
function greet(names: string[]): string;
function greet(value: string | string[]): string {
if (Array.isArray(value)) {
return `مرحباً ${value.join(", ")}`;
}
return `مرحباً ${value}`;
}
console.log(greet("أحمد")); // مرحباً أحمد
console.log(greet(["أحمد", "محمد"])); // مرحباً أحمد, محمد
حل المشاكل الشائعة
🔴 المشكلة 1: Expected X arguments, but got Y
السبب: عدد المعاملات غير متطابق.
function add(a: number, b: number): number {
return a + b;
}
add(5); // ❌ Expected 2 arguments, but got 1
الحل: مرر العدد الصحيح من المعاملات، أو اجعلها اختيارية.
🔴 المشكلة 2: Type 'X' is not assignable to type 'Y'
السبب: نوع المعامل أو القيمة المرجعة مختلف.
function add(a: number, b: number): number {
return "5"; // ❌ يجب أن يكون number
}
الحل: تأكد من تطابق الأنواع.
🔴 المشكلة 3: A function whose declared type is neither 'void' nor 'any' must return a value
السبب: نسيت return.
function add(a: number, b: number): number {
a + b; // ❌ لا return
}
الحل: أضف return.
🔴 المشكلة 4: Argument of type 'string' is not assignable to parameter of type 'number'
السبب: تمرير نوع خاطئ.
function greet(name: string) {}
greet(25); // ❌
الحل: مرر النوع الصحيح.
جدول الأوامر الأساسية
| الأمر | الوظيفة |
|---|---|
function name(): type { } | تعريف دالة |
const fn = (): type => { } | دالة سهمية |
param?: type | معامل اختياري |
param: type = default | قيمة افتراضية |
...params: type[] | معاملات متبقية |
: void | لا قيمة مرجعة |
: never | لا يحدث أبداً |
function f(): T | Generics |
قائمة تحقق نهائية
| المهمة | الحالة |
|---|---|
| فهم تعريف الدوال واستدعاؤها | ⬜ |
| استخدام المعاملات والقيم المرجعة | ⬜ |
| المعاملات الاختيارية والافتراضية | ⬜ |
| Rest Parameters | ⬜ |
| Function Overloads | ⬜ |
| Callbacks | ⬜ |
| Generics | ⬜ |
| حل التمارين الثمانية | ⬜ |
ماذا بعد هذا المقال؟
الآن بعد أن أتقنت الدوال، أنت جاهز للمقال التالي:
- الفئات (Classes) — البرمجة كائنية التوجه.
- الأدوية (Generics) — تعمق في الأدوية.
- الأنواع المتقدمة — Utility Types.
الخلاصة
في هذا المقال، تعلمت:
- ✅ تعريف الدوال بأنواع.
- ✅ أنواع المعاملات (اختيارية، افتراضية، متبقية).
- ✅ أنواع القيم المرجعة.
- ✅ Function Types و Callbacks.
- ✅ Higher-Order Functions.
- ✅ Function Overloads.
- ✅ الدوال العودية.
- ✅ Async/Await.
- ✅ Generics في الدوال.
تذكر: الدوال هي أدواتك الأساسية لتنظيم الكود. كلما أتقنتها، كلما أصبح كودك أنظف وأسهل صيانة.
هل أتقنت الدوال؟ شاركنا في التعليقات!
الواجهات في TypeScript — دليل شامل Interfaces 2026
الفئات في TypeScript — دليل شامل Classes 2026
📚 مقالات ذات صلة
مشروع Node.js مع TypeScript — API كامل 2026
مشروع عملي لبناء API كامل بـ Node.js و Express و TypeScript — خطوة بخطوة مع الكود الكامل والشرح
مشروع React مع TypeScript — تطبيق مهام كامل 2026
مشروع عملي لبناء تطبيق مهام (Todo App) بـ React و TypeScript — خطوة بخطوة مع الكود الكامل والشرح
الأنواع المتقدمة في TypeScript — دليل شامل 2026
دليل عملي مفصل للأنواع المتقدمة في TypeScript — Union, Intersection, Conditional, Mapped, Template Literal، مع تمارين وحلول