تفهم ما يُفعّله الوضع الصارم فعلا وتعرف كيف تعالج الأخطاء النموذجية التي يكشفها في مشروع قائم.
افتح هذا الدرس في Kodokon"strict": true ليس خيارا واحدا بل تجميعة تُفعّل عائلة كاملة من الفحوص: strictNullChecks وnoImplicitAny وstrictFunctionTypes وstrictBindCallApply وstrictPropertyInitialization وnoImplicitThis وuseUnknownInCatchVariables وalwaysStrict. وقد يضيف كل إصدار جديد من TypeScript المزيد: فتفعيل strict يشترككَ في الفحوص المستقبلية. ويبقى بالإمكان تعطيل كل عَلَم على حدة، ما يتيح هجرة تدريجية على قاعدة كود قائمة.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true
}
}أعلى العَلَمين أثرا هما strictNullChecks وnoImplicitAny. يُزيل الأول null وundefined من كل الأنواع: فكل قيمة قد تغيب يجب أن تُصرَّح T | undefined وتُعالَج قبل الاستعمال. ويرفض الثاني أن يرتد مُعامل بلا شرح إلى any. ومعا، يقضيان على العائلتين الكبيرتين من أخطاء JavaScript: "cannot read property of undefined" وانتشار القيم غير المُتحقَّق منها. ويُكمِل useUnknownInCatchVariables الصورة: متغيّر catch يصير unknown، لأن JavaScript تتيح رمي أي شيء.
function findPort(
env: Record<string, string | undefined>
): number {
const raw = env["PORT"];
if (raw === undefined) {
return 3000;
}
return Number.parseInt(raw, 10);
}
declare function riskyOperation(): void;
try {
riskyOperation();
} catch (err) {
const message =
err instanceof Error ? err.message : String(err);
console.error(message);
}أخطاء الهجرة الشائعة وعلاجاتها الحقيقية. "Object is possibly undefined": فضّل التضييق (if)، أو التسلسل الاختياري ?.، أو قيمة افتراضية بـ?? على تأكيد عدم النُّلية !، الذي ينقل الانهيار إلى مكان آخر لا أكثر. "Property has no initializer" (strictPropertyInitialization): هيّئ في الباني بدل اللجوء إلى ! على الحقل. واحذر أيضا فخ ?? مقابل ||: فـport || 3000 يستبدل 0 و"" أيضا، بينما port ?? 3000 يستبدل null وundefined فقط.
interface Settings { retries?: number }
function resolveRetries(s: Settings): number {
const bad = s.retries || 3;
const good = s.retries ?? 3;
return good;
}
const names = ["Ada", "Linus"];
const first = names[0];
const upper = first?.toUpperCase() ?? "N/A";خارج التجميعة، تستحق ثلاثة خيارات نقاشا مع الفريق. noUncheckedIndexedAccess يضيف undefined إلى كل وصول مُفهرَس (arr[i]، dict[key]): أأمن، لكنه مُسهِب في كود معالجة المصفوفات - فتعتمده فرق كثيرة على المشاريع الجديدة فقط. وexactOptionalPropertyTypes يميّز "الخاصية غائبة" عن "الخاصية مضبوطة على undefined"، وهو حاسم للفرقعات. وskipLibCheck يتخطّى فحص ملفات .d.ts لتبعياتك: مفاضلة مقصودة بين زمن البناء وكشف التعارضات بين المكتبات.
"strict": true بالضبط في tsconfig.json؟retries?: number مضبوطا على 0، ما الفرق بين retries || 3 وretries ?? 3؟// @ts-expect-error على // @ts-ignore لتعليم دَين الأنواع؟