خطأ TypeScript النموذجي: الخاصية 'value' غير موجودة في HTMLElement

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

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

ابدأ الدورة

«الخاصية value غير موجودة»: كيف توفق بين TypeScript وDOM

\n\n

هل سبق لك أن كتبت معالج نموذج بسيط بلغة TypeScript، وقمت بتشغيل التجميع — وحصلت على سطر أحمر في وحدة التحكم: «The property 'value' does not exist on value of type 'HTMLElement'»؟ إذا كان الأمر كذلك — فأنت لست وحدك. هذا السؤال جمع آلاف المشاهدات على Stack Overflow، واليوم سنحلّه نهائياً.

\n\n

يحدث الخطأ عندما تحاول الحصول على .value من عنصر يعتبره TypeScript مجرد HTMLElement. المشكلة أن HTMLElement هو نوع أساسي، والخاصية value موجودة فقط في HTMLInputElement و HTMLTextAreaElement والورثة المشابهين. TypeScript صارم: لن يسمح بالوصول إلى خاصية غير موجودة (من وجهة نظره).

\n\n

لكن هذا ليس خطأ — بل ميزة. TypeScript يحميك من أخطاء وقت التشغيل. دعنا نفهم كيفية تحديد النوع بشكل صحيح وتحسين أداء الكود في نفس الوقت.

\n\n

لماذا يعترض TypeScript؟

\n\n

تخيل: أنت تكتب كوداً لحقل إدخال:

\n\n
const input = document.getElementById('myInput');\nconsole.log(input.value); // ❌ خطأ!
\n\n

الطريقة getElementById تُرجع النوع HTMLElement | null. HTMLElement لا يحتوي على الخاصية value. يوجد innerHTML و className و style — لكن ليس value. TypeScript يقول بصراحة: «لست متأكداً من أن هذا العنصر يحتوي على value».

\n\n

بينما أنت متأكد أنه <input>. كيف تشرح ذلك للمترجم؟

\n\n

الطريقة 1: تحويل الأنواع (Type Assertion)

\n\n

الطريقة الأكثر شيوعاً وسرعة هي استخدام as:

\n\n
const input = document.getElementById('myInput') as HTMLInputElement;\nconsole.log(input.value); // ✅ كل شيء يعمل
\n\n

الآن TypeScript يعلم: هذا HTMLInputElement، الذي يحتوي على value. بسيط وفعال. لكن هناك فارق بسيط: إذا لم يكن العنصر في الواقع <input> (مثلاً، هو <div>)، ستحصل على undefined في وقت التشغيل. TypeScript لن يساعدك — فهو يصدق تأكيداتك.

\n\n

الطريقة 2: التحقق من النوع عبر instanceof

\n\n

نهج أكثر أماناً — التحقق أثناء وقت التشغيل:

\n\n
const element = document.getElementById('myInput');\nif (element instanceof HTMLInputElement) {\n    console.log(element.value); // ✅ TypeScript يضيق النوع تلقائياً\n} else {\n    console.error('العنصر ليس input');\n}
\n\n

هذه الطريقة لا تحل مشكلة الأنواع فحسب، بل تجعل الكود أكثر موثوقية. أنت تتحقق صراحة من أن العنصر هو بالضبط ما تتوقعه. للأغراض التعليمية، أوصي بهذه الطريقة: فهي تعلمك التفكير في الأنواع.

\n\n

الطريقة 3: الدوال العامة (Generics)

\n\n

للمستخدمين المتقدمين — إنشاء غلاف باستخدام الأدوية:

\n\n
function getInputElement<T extends HTMLElement>(id: string): T | null {\n    const element = document.getElementById(id);\n    if (element instanceof T) { // ❌ لا يمكن فعل ذلك، T هو نوع وليس قيمة\n        return element;\n    }\n    return null;\n}
\n\n

للأسف، في TypeScript لا يمكن التحقق من instanceof مع الأدوية مباشرة. لكن يمكن استخدام التحميل الزائد للدوال أو المصانع. للمشاريع البسيطة، تكفي الطريقتان الأوليتان.

\n\n

تحسين الأداء: لماذا النوع مهم

\n\n

قد تسأل: «ما علاقة الأنواع بالسرعة؟» علاقة مباشرة. عندما يعرف TypeScript النوع الدقيق للعنصر، فإنه يولد كود JavaScript أكثر كفاءة. لننظر إلى مثال:

\n\n
// سيء: TypeScript لا يعرف النوع\nfunction getValue(id: string): string {\n    const el = document.getElementById(id);\n    // في كل استدعاء — تحقق وتحويل\n    return (el as HTMLInputElement).value || '';\n}\n\n// حس                

المدونات

توصيات الكتب