تقنية
لماذا TypeScript ضروري في المشاريع الكبيرة
كيف يلتقط التحقّق الثابت من الأنواع الأخطاء مبكراً، ويحسّن تجربة المطوّر، ويعمل بوصفه توثيقاً حيّاً في التطبيقات التي تكبر.

أبعد من أمان الأنواع
يُسوَّق TypeScript عادةً على أنّه يلتقط الأخطاء وقت الترجمة، وهو يفعل ذلك. لكن لو كانت تلك كل الفائدة لكانت المقايضة أقلّ وضوحاً ممّا هي عليه — فكثير من تلك الأخطاء كان سيظهر عند أول تحميل للصفحة على أي حال.
العائد الحقيقي هو كل ما يصير ممكناً لأنّ الأنواع موجودة: إكمال تلقائي يعرف بياناتك أنت، وإعادة هيكلة تثق بها، وتوثيق لا يستطيع أن يتقادم لأنّه هو الكود نفسه.
الأنواع توثيق لا يستطيع الكذب
التعليق الذي يصف وسائط دالّة صحيحٌ يوم كتابته. أمّا النوع فصحيح إلى الأبد، لأنّ البناء يفشل حين يكفّ عن الصحّة.
type ContactSubmission = {
name: string;
email: string;
phone: string | null;
message: string;
submittedAt: Date;
};
من يقرأ ذلك يعرف أنّ phone قد يكون غائباً، وأنّ submittedAt من نوع Date لا سلسلة نصية — وهما بالضبط الحقيقتان اللتان تنتجان أخطاء وقت التشغيل حين يُفترضان خطأً. ولم يضطرّ أحد إلى تذكّر تدوين ذلك.
إعادة الهيكلة تكفّ عن كونها مخيفة
هنا يسدّد ثمنه. إعادة تسمية حقل عبر أربعين ملفاً عملية من خمس عشرة ثانية حين يستطيع المترجم إيجاد كل إشارة إليه، وبعد ظهر كامل من البحث والدعاء حين لا يستطيع.
والأمر نفسه ينطبق على تغيير الشكل. اجعل حقلاً واحداً قابلاً للعدم، فيضيء فوراً كل موضع افترض غير ذلك:
// Before: every caller assumed a cover image existed
type Project = { title: string; coverImageUrl: string };
// After: the compiler now flags all 14 call sites
type Project = { title: string; coverImageUrl: string | null };
وبلا أنواع يبقى ذلك التغيير غير مرئي إلى أن تعرض صفحةٌ صورةً مكسورة على زائر حقيقي.
حيث يكسب أكثر ما يكسب: الحدود
داخل ملف واحد، الأنواع راحة. أمّا عند الحدود فهي الفرق بين خطأ يُلتقط في المحرّر وخطأ يلتقطه زبون.
والحدود التي تهمّ في تطبيق Next.js نموذجي هي قاعدة البيانات، وإرسال النماذج، وواجهات الأطراف الثالثة. و Prisma يولّد الأنواع من المخطّط، فجانب قاعدة البيانات مغطّى مجاناً. أمّا النماذج والواجهات فلا — وهنا الفخّ:
// This compiles. It is also a lie.
const body = (await request.json()) as ContactSubmission;
as تؤكّد، ولا تتحقّق. ذلك الطلب جاء من الإنترنت المفتوح وقد يحتوي أي شيء على الإطلاق، وأنت للتوّ أخبرت المترجم أن يكفّ عن القلق بشأنه.
حلّله بدلاً من ذلك:
const parsed = ContactSchema.safeParse(await request.json());
if (!parsed.success) {
return Response.json({ error: "Invalid payload" }, { status: 400 });
}
// parsed.data is now genuinely a ContactSubmission
وهنا بالضبط يكسب مدقّق المخطّطات مكانه — فهو ينتج نوعاً ويتحقّق من القيمة، فيصير الضمان حقيقياً لا مؤكَّداً بالدعوى. لا تلجأ إلى as إلا حين تعرف شيئاً لا يستطيع المترجم معرفته، وعامل كل استعمال لها على أنّه دَين صغير مدوَّن.
الكلفة بصدق
البداية أبطأ. والكود العامّ (generic) قد يصير مزعجاً فعلاً. وفي كل مشروع مرحلة تجد نفسك فيها تصارع نظام الأنواع بدل أن تصارع المشكلة — وهي غالباً علامة على أنّ النموذج خاطئ، وأحياناً على أنّ الأنواع خاطئة.
وتنقلب المقايضة إلى الربح مع الحجم ومع الوقت. مشروع عطلة نهاية أسبوع لا يحتاجه. أمّا ما سيلمسه شخص ثانٍ، أو ما ستعود إليه بعد ستة أشهر وقد نسيته كلّه، فيحتاجه.
أستعمله في كل شيء — بما في ذلك نظام إدارة المحتوى الخاص بهذا الموقع، حيث تمتدّ الأنواع من مخطّط Prisma إلى النموذج، وفي أعمال العملاء مثل نظام ERP، حيث نموذج البيانات هو المنتج كلّه، والخطأ في حقل واحد ليس مشكلة شكلية.