مقدمة: لماذا يصرخ TypeScript في الفراغ؟
\n\nأنت تكتب كودًا في TypeScript، كل شيء يبدو منطقيًا، لكن فجأة يُصدر المترجم: "error TS2533: Object is possibly 'null' or 'undefined'". هل هذا مألوف؟ هذا الخطأ هو أحد أكثر "المزالق" شيوعًا للمبتدئين. وفقًا لبيانات Stack Overflow، حصد سؤال حول قمعه أكثر من 100,000 مشاهدة وأصبح كلاسيكيًا.
\n\nلكن دعنا ننظر أعمق. TypeScript ليس مجرد "JavaScript صارم". نظام الأنواع الخاص به، خاصة وضع strictNullChecks، يجعلك تعالج بوضوح الحالات التي قد تكون فيها القيمة null أو undefined. وهذا ليس خطأ، بل ميزة. خطأ TS2533 هو حماية من أخطاء وقت التشغيل التي تؤدي غالبًا في JavaScript إلى Cannot read property of null.
في هذه المقالة، سنحلل:
\n- \n
- ما هو strictNullChecks وكيف يعمل "تحت الغطاء" \n
- لماذا يحدث خطأ TS2533 \n
- 5 طرق لقمعها (من البسيطة إلى المتقدمة) \n
- متى تكون كل طريقة مناسبة، ومتى لا تكون \n
هيا بنا نفهم خطأ null في TypeScript مرة واحدة وإلى الأبد!
\n\nكيف يعمل strictNullChecks تحت الغطاء
\n\nافتراضيًا في TypeScript (بدءًا من الإصدار 2.0)، يكون خيار strictNullChecks مفعلًا. ماذا يعني هذا؟ سابقًا، كان null و undefined يُعتبران أنواعًا فرعية لأي نوع. أي أنه يمكنك تعيين null لمتغير من النوع string وكان TypeScript يصمت. هذا كان يبسط الكود، لكنه كان يؤدي إلى أخطاء.
في وضع strictNullChecks، فإن النوعين null و undefined هما كيانان منفصلان. المتغير من النوع string يمكن أن يحتوي فقط على سلسلة نصية. إذا كنت تريد السماح بـ null، فيجب عليك تحديد string | null صراحةً.
مثال: كيف يبدو الخطأ
\n\n// مثال 1: خطأ TS2533 الكلاسيكي\ninterface User {\n name: string;\n email?: string; // اختياري — قد يكون undefined\n}\n\nfunction getUserEmail(user: User): string {\n // خطأ TS2533: Object is possibly 'undefined'\n return user.email.toUpperCase(); \n}\n\n// مثال 2: العمل مع DOM\nconst button = document.querySelector('button');\n// خطأ TS2533: Object is possibly 'null'\nbutton.addEventListener('click', () => console.log('clicked'));\n\n\nفي المثال الثاني، document.querySelector قد يُرجع null إذا لم يتم العثور على العنصر. TypeScript يحذرك: "مرحبًا، هل أنت متأكد من أن الزر موجود؟"
5 طرق لقمع خطأ TS2533
\n\nالآن ننتقل إلى الأهم — كيفية إزالة الخطأ. أدناه 5 طرق مجربة، من البسيطة إلى المتقدمة. اختر حسب الموقف.
\n\n1. عامل التأكيد غير الفارغ (!)
\n\nأسرع طريقة هي وضع علامة التعجب ! بعد التعبير. هذا يخبر TypeScript: "أنا أعلم أن هذا ليس null، ثق بي".
// استخدام ! للقمع\nconst button = document.querySelector('button')!;\nbutton.addEventListener('click', () => console.log('clicked'));\n\n// للخاصية الاختيارية\nfunction getUserEmail(user: User): string {\n return user.email!.toUpperCase();\n}\n\n\nمتى تستخدم: عندما تكون متأكدًا تمامًا أن القيمة ليست null. على سبيل المثال، إذا كنت قد تحققت للتو من وجود العنصر في DOM. لكن كن حذرًا: إذا أخطأت — ستحصل على خطأ وقت التشغيل.
\n\n2. الربط الاختياري (?.) والدمج مع القيم الفارغة (??)
\n\nطريقة حديثة وآمنة. العامل ?. يسمح بالوصول إلى الخاصية فقط إذا كان الكائن ليس null/undefined. و ?? يحدد قيمة افتراضية.
function getUserEmail(user: User): string {\n // إذا كان email undefined — سنرجع سلسلة فارغة\n return user.email?.toUpperCase() ?? '';\n}\n\n// العمل مع DOM\ndocument.querySelector('butt