كيفية إنشاء كائن بناءً على واجهة في TypeScript: شرح كامل مع كود
\n\nهل سبق لك أن واجهت موقفًا حيث TypeScript "يصرخ" عليك حرفيًا لأنك تحاول إنشاء كائن لا يتوافق مع الواجهة؟ مألوف؟ إذا كنت تعمل مع TypeScript لمدة أسبوع على الأقل، فمن المحتمل أنك رأيت هذا الخطأ:
\n\nType '{}' is missing the following properties from type 'User': name, age\n\nهذه واحدة من أكثر المشكلات شيوعًا على Stack Overflow (عشرات الآلاف من المشاهدات)، واليوم سنحلها مرة واحدة وإلى الأبد. في هذه المقالة، ستتعلم كيفية إنشاء كائن بناءً على واجهة في TypeScript، وما هي الطرق المتاحة ومتى تستخدم كل منها.
\n\nلماذا هذا الموضوع مهم جدًا؟
\n\nTypeScript هي إضافة فوق JavaScript تضيف كتابة ثابتة. واجهات TypeScript هي أداة قوية لوصف هيكل الكائنات. لكن المبتدئين غالبًا ما يرتبكون: "لقد أعلنت عن واجهة، ولكن كيف يمكنني الآن إنشاء كائن حقيقي؟"
\n\nبدون فهم صحيح لهذه الآلية، ستضيع ساعات في تصحيح الأخطاء، أو ما هو أسوأ، استخدام any - وهذا طريق مباشر لفقدان جميع مزايا TypeScript.
الطريقة 1: التعيين المباشر (الأبسط)
\n\nالطريقة الأكثر وضوحًا لإنشاء كائن وفقًا لواجهة TypeScript هي ببساطة تعيين حرفية كائن لمتغير بنوع الواجهة:
\n\ninterface User {\n name: string;\n age: number;\n email?: string; // حقل اختياري\n}\n\n// ✅ صحيح: الكائن يتوافق تمامًا مع الواجهة\nconst user: User = {\n name: "آنا",\n age: 28,\n email: "anna@example.com"\n};\n\n// ✅ صحيح أيضًا: يمكن حذف الحقل الاختياري\nconst userMinimal: User = {\n name: "إيفان",\n age: 35\n};\n\nهذا يعمل، ولكن هناك فارق بسيط: سيتحقق TypeScript من أن الكائن يحتوي على جميع الحقول الإلزامية. إذا نسيت name أو age، فسيصدر المترجم خطأ.
❌ خطأ نموذجي للمبتدئين
\n\n// ❌ خطأ! الحقل الإلزامي 'age' مفقود\nconst badUser: User = {\n name: "بيتر"\n};\n\nالطريقة 2: استخدام عامل التشغيل as (تحويل النوع)
\n\nفي بعض الأحيان تحتاج إلى إنشاء كائن تدريجيًا، على سبيل المثال، ملؤه من مصادر مختلفة. في مثل هذه الحالات، يمكنك استخدام عامل التشغيل as:
interface Config {\n apiUrl: string;\n timeout: number;\n retries: number;\n}\n\n// إنشاء كائن فارغ مع تحويل النوع\nconst config = {} as Config;\n\n// الآن يمكن إضافة الحقول واحدًا تلو الآخر\nconfig.apiUrl = "https://api.example.com";\nconfig.timeout = 5000;\nconfig.retries = 3;\n\n// ✅ يعمل، ولكن كن حذرًا!\n\n⚠️ تحذير: هذه الطريقة تعطل التحقق من الأنواع في مرحلة إنشاء الكائن. قد تنسى عن طريق الخطأ حقلًا إلزاميًا وتكتشف ذلك فقط في وقت التشغيل. استخدم as فقط عندما تكون متأكدًا من أن جميع الحقول سيتم ملؤها.
الطريقة 3: دالة المصنع (موصى بها)
\n\nأفضل طريقة لإنشاء كائن بناءً على واجهة في TypeScript هي كتابة دالة مصنع. هذا يوفر أمانًا بنسبة 100% للأنواع وإمكانية تعيين قيم افتراضية:
\n\ninterface Product {\n id: number;\n title: string;\n price: number;\n inStock: boolean;\n description?: string;\n}\n\n// دالة مصنع مع معلمات افتراضية\nfunction createProduct(\n id: number,\n title: string,\n price: number,\n inStock: boolean = true,\n description?: string\n): Product {\n return {\n id,\n title,\n price,\n inStock,\n ...(description && { description })\n };\n}\n\n// الاستخدام\nconst laptop = createProduct(1, "لابتوب", 999.99);\nconst phone = createProduct(2, "هاتف ذكي", 599.99, false, "هاتف ممتاز");\n\nconsole.log(laptop); // { id: 1, title: 'لابتوب', price: 999.99, inStock: true }\nconsole.log(phone)