القيم الافتراضية لكائن TypeScript في الوسائط: دليل شامل

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

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

ابدأ الدورة

مقدمة: لماذا هذا السؤال شائع جدًا؟

\n\n

كل مطور ينتقل من JavaScript إلى TypeScript أو يكتب بهذه اللغة، سيواجه عاجلاً أم آجلاً مشكلة: كيف نحدد قيمة افتراضية لكائن يُمرر إلى دالة؟ على Stack Overflow، حصد هذا السؤال آلاف المشاهدات وعشرات الإجابات. لماذا؟ لأن المهمة التي تبدو بسيطة — "إذا لم يُمرر الكائن، استخدم كائنًا فارغًا" — تتحول في TypeScript إلى مغامرة كاملة مع الأنواع والواجهات والتفكيك.

\n\n

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

\n\n

المشكلة: ما الخطأ في الطريقة التقليدية؟

\n\n

لنفترض أن لدينا دالة تستقبل كائنًا يحتوي على إعدادات:

\n\n
function createUser(config: { name?: string; age?: number }) {\n  // ...\n}\n\ncreateUser(); // خطأ! يجب تمرير وسيطة\n
\n\n

في JavaScript، كان بإمكاننا كتابة function createUser(config = {}) وتنتهي المشكلة. لكن في TypeScript، هذه الحيلة لا تعمل: المترجم سيشتكي من عدم تطابق الأنواع. لماذا؟ لأن الكائن الفارغ {} لا يتوافق مع الواجهة { name?: string; age?: number } — فهو ببساطة لا يحتوي على هذه الخصائص.

\n\n

وهنا تبدأ المتعة. دعنا نستعرض جميع طرق الحل.

\n\n

الطريقة 1: التفكيك مع تعيين القيم الافتراضية

\n\n

الطريقة الأكثر أناقة وشيوعًا هي استخدام التفكيك مباشرة في بارامترات الدالة. يمكنك استخراج خصائص الكائن وتعيين قيم افتراضية لها فورًا:

\n\n
function createUser({ name = "ضيف", age = 18 }: { name?: string; age?: number } = {}) {\n  console.log(`تم إنشاء مستخدم: ${name}، العمر: ${age}`);\n}\n\ncreateUser(); // "تم إنشاء مستخدم: ضيف، العمر: 18"\ncreateUser({ name: "آمنة" }); // "تم إنشاء مستخدم: آمنة، العمر: 18"\ncreateUser({ age: 25 }); // "تم إنشاء مستخدم: ضيف، العمر: 25"\n
\n\n

لاحظ = {} في النهاية. هذه هي القيمة الافتراضية للكائن نفسه. إذا لم تمرر وسيطة، يستخدم TypeScript كائنًا فارغًا، ثم يقوم التفكيك بتعيين القيم الافتراضية لكل خاصية.

\n\n

المزايا: نظيف، موجز، ويعمل بكفاءة.
\nالعيوب: تحتاج إلى تحديد النوع لكل خاصية بشكل صريح.

\n\n

الطريقة 2: استخدام واجهة مع Partial

\n\n

إذا كان الكائن كبيرًا، فإن وصف جميع الأنواع في البارامترات ليس أفضل ممارسة. نخرج الواجهة بشكل منفصل ونستخدم Partial<T>:

\n\n
interface UserConfig {\n  name: string;\n  age: number;\n  email: string;\n  isAdmin: boolean;\n}\n\nfunction createUser(config: Partial<UserConfig> = {}) {\n  const defaults: UserConfig = {\n    name: "ضيف",\n    age: 18,\n    email: "noemail@example.com",\n    isAdmin: false\n  };\n  \n  const mergedConfig = { ...defaults, ...config };\n  console.log(mergedConfig);\n}\n\ncreateUser({ name: "خالد" });\n// { name: "خالد", age: 18, email: "noemail@example.com", isAdmin: false }\n
\n\n

هنا، Partial<UserConfig> يجعل جميع الخصائص اختيارية. داخل الدالة، نقوم بدمج القيم الافتراضية مع القيم المُمررة. يعمل بشكل ممتاز، لكنه يتطلب دمجًا يدويًا.

\n\n

الطريقة 3: الطريقة التقليدية مع التحقق

\n\n

أحيانًا تحتاج إلى تحكم أكبر. على سبيل المثال، إذا كنت تريد تعيين قيمة افتراضية فقط لـ undefined، وليس لـ null. نستخدم الطريقة الكلاسيكية مع if:

\n\n
function createUser(config?: UserConfig) {\n  const name = config?.name ?? "ضيف";\n  const age = config?.age ?? 18;\n  const email = config?.email ?? "noemail@example.com";\n  \n  console.log({ name, age, email });\n}\n\ncreateUser();                

المدونات

توصيات الكتب