مقدمة موسعة: ما هي ملفات التصريح (.d.ts) ولماذا تمثل العمود الفقري لمنظومة TypeScript؟
في رحلتنا التعليمية الشاملة ضمن دورة TypeScript عبر منصة كود التطور، نصل إلى أحد أكثر المواضيع المحورية وحجر الزاوية الذي يربط بين عالمين مختلفين تماماً في فلسفة التنفيذ: عالم JavaScript الديناميكي وعالم TypeScript الصارم القائم على الفحص النوعي في وقت الترجمة (Compile Time). هذا الجسر المعماري يُعرف بـ ملفات التصريح (Type Declaration Files) والتي تحمل الامتداد الشهير .d.ts.
هناك مفهوم خاطئ شائع لدى بعض المطورين المبتدئين بأن ملفات التصريح هي ملفات بصيغة JSON؛ والحقيقة التقنية الصارمة هي أن ملفات .d.ts هي ملفات شفرة مصدرية مكتوبة بصياغة TypeScript نقية وخاصة، لكنها تخضع لقاعدة واحدة مطلقة تحكم كل سطر بداخلها: احتوائها على توصيفات مجردة للأنواع (Type Signatures) دون احتواء أي سطر برمجي تنفيذي على الإطلاق (No Implementation Code).
عندما تقوم ببناء مشروع TypeScript، يقوم المترجم بمراقبة الكود والتحقق من صحة استدعاء الدوال وتمرير المعاملات. ولكن ماذا يحدث عندما تستورد مكتبة كُتبت قبل عشر سنوات بلغة JavaScript نقية مثل jQuery أو Lodash أو حزمة داخلية خاصة بشركتك؟ محرك JavaScript يشغل هذه الحزم دون مشكلة، لكن مترجم TypeScript يقف عاجزاً لأنه لا يرى داخل ملفات .js أي معلومات توضح ما إذا كانت الدالة تأخذ رقماً أم نصاً، أو ما إذا كان الكائن يحتوي على الحقل المطلوب. هنا تتدخل ملفات .d.ts لتلعب دور “الكتالوج التوجيهي” أو “العقد الشكلي” الذي يُعلم المترجم بالهيكل الدقيق للأنواع دون الحاجة لإعادة كتابة المكتبة الأصلية.
القسم 1: التشريح الداخلي لملفات .d.ts وكيف يتعامل المترجم معها
لفهم الآلية التي تعمل بها ملفات التصريح، يجب التمييز بوضوح بين دورة حياة ملفات التطوير التنفيذية (.ts) وملفات التصريح (.d.ts):
| وجه المقارنة | الملفات التنفيذية (.ts) | ملفات التصريح (.d.ts) |
|---|---|---|
| المحتوى البرمجي | تنفيذ فعلي (منطق حسابي، متغيرات، حلقات تكرار، دوال حية) بالإضافة للأنواع. | توصيفات تصريحية مجردة (أنواع، واجهات، تواقيع دوال، كلاسات هيكلية دون أجسام). |
| مخرجات التجميع (Compilation Output) | تُترجم إلى ملفات JavaScript حقيقية بصيغة .js تُنفذ في المتصفح أو Node.js. | لا ينتج عنها أي ملف JavaScript إطلاقاً؛ تُستخدم في وقت الترجمة وتُحذف تماماً. |
| وجود الكلمة المفتاحية declare | اختيارية ونادرة، تُستخدم فقط عند الإشارة لمتغير خارجي في بيئة التشغيل. | إلزامية وشائعة جداً للإعلان عن كائنات ودوال موجودة بالفعل في مكان آخر. |
| الوظيفة الأساسية | بناء منطق الأعمال الخاص بالتطبيق (Business Logic). | توفير التلميحات الذكية (IntelliSense) والأمان النوعي لمحررات الأكواد والمترجم. |
عندما تضع الكلمة المفتاحية declare داخل ملف التصريح، فأنت توجه رسالة مباشرة لمترجم TypeScript مفادها:
“ثق بي، هذا المتغير أو هذه الدالة موجودة بالفعل في بيئة التشغيل (سواء في الذاكرة أو عبر وسم script خارجي أو عبر مكتبة)، ومهمتك هنا هي فقط مراقبة طريقتي في استخدامها وتطبيق قواعد الأمان النوعي عليها دون محاولة توليد شفرة تنفيذية لها.”
القسم 2: الكلمات المفتاحية والأدوات الأساسية داخل ملفات التصريح
تعتمد كتابة ملفات .d.ts على مجموعة محددة من الكلمات المفتاحية التوجيهية التي يجب على كل مهندس برمجيات إتقانها:
1. الكلمة المفتاحية declare مع المتغيرات والدوال العامة
تُستخدم للإعلان عن متغيرات أو كائنات بيئية عامة توفرها بيئة التشغيل، مثل المتغيرات التي تحقنها خوادم الويب أو إضافات المتصفح داخل كائن window:
// env-globals.d.ts
// الإعلان عن متغير عام محقون في بيئة المتصفح
declare const __APP_VERSION__: string;
declare const __IS_PRODUCTION__: boolean;
// الإعلان عن دالة عامة يوفرها نظام التتبع التحليلي
declare function sendAnalyticsEvent(eventName: string, metadata: Record<string, unknown>): void;2. الإعلان عن الفئات (Classes) داخل ملفات التصريح
عند توصيف فئة داخل ملف .d.ts، يتم كتابة أسماء الخصائص وتواقيع دوال البناء والطرق فقط، ويُمنع منعاً باتاً كتابة الأقواس المعقوفة الحاوية لمنطق الدالة:
// logger.d.ts
declare class ExternalLogger {
// تحديد حقول الفئة ونوع الوصول
public readonly logDirectory: string;
private maxFileSize: number;
// توقيع دالة البناء دون كتابة جسم الدالة
constructor(directoryPath: string, maxMb?: number);
// تواقيع الدوال
public writeLog(level: "INFO" | "WARN" | "ERROR", message: string): boolean;
public clearLogs(): Promise<void>;
}3. الإعلان عن مساحات الأسماء المحيطة (Ambient Namespaces)
تُستخدم مساحات الأسماء داخل ملفات التصريح لتجميع الدوال والواجهات ذات الصلة في سياق تنظيمي موحد يحاكي الكائنات العامة التابعة للمكتبات الكلاسيكية:
// utility-library.d.ts
declare namespace StringHelperLib {
interface FormattingOptions {
trimWhitespace?: boolean;
capitalizeFirstLetter?: boolean;
maxCharacters?: number;
}
function format(text: string, options?: FormattingOptions): string;
function slugify(title: string): string;
}القسم 3: توليد ملفات التصريح تلقائياً عبر المترجم (Automatic Declaration Generation)
في معظم الأوقات، إذا كنت تبني مكتبة أو حزمة برمجية بلغة TypeScript ليتم نشرها على مستودع NPM واستهلاكها بواسطة مطورين آخرين، لن تضطر لكتابة ملفات .d.ts يدوياً من الصفر! يمتلك مترجم TypeScript (tsc) القدرة الكاملة على فحص ملفاتك البرمجية واستخراج ملفات التصريح المطابقة لها آلياً وبدقة متناهية.
إعدادات ملف tsconfig.json للتوليد الآلي
لتفعيل هذه الميزة، نضبط الخواص التالية في قسم compilerOptions داخل ملف tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
/* الخواص الجوهرية لتوليد ملفات التصريح */
"declaration": true, // توليد ملفات .d.ts لكل ملف .ts
"declarationMap": true, // توليد خرائط .d.ts.map لتمكين ميزة Go-to-Definition للكود المصدري الأصلي
"emitDeclarationOnly": false, // إذا كانت true، سيولد فقط ملفات الأنواع دون توليد ملفات .js
"declarationDir": "./dist/types", // عزل ملفات التصريح في مجلد مخصص داخل حزمة التوزيع
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}عند تشغيل الأمر npx tsc، سيقوم المترجم بتوليد ملف .js التنفيذي بجواره ملف .d.ts الوصفي. هذا يضمن أن أي مستخدم يستورد مكتبتك سيحصل على فحص نوعي فوري وإكمال تلقائي كامل في محرره البرمجي، حتى لو كان مشروعه مبنياً بلغة JavaScript ويستخدم بيئة مثل Visual Studio Code.
القسم 4: التعامل مع الحزم الخارجية ومستودع DefinitelyTyped (@types)
عندما تدمج مكتبات خارجية في مشروعك، تنقسم الحزم البرمجية على مستودع NPM إلى ثلاثة أصناف رئيسية:
1. حزم تحتوي على أنواع مدمجة (Built-in Types)
هذه الحزم تكون مكتوبة أصلاً بلغة TypeScript أو قام مطوروها بتوليد ملفات .d.ts وتضمينها داخل مجلد الحزمة، مع الإشارة إليها في ملف package.json عبر الحقل "types" أو "typings" (مثل مكتبات axios و rxjs و date-fns). لا تتطلب هذه الحزم أي إجراء إضافي منك؛ بمجرد تثبيتها، تعمل الأنواع تلقائياً.
2. حزم JavaScript نقية مدعومة عبر مستودع DefinitelyTyped
حزم كُتبت بلغة JavaScript نقية ولم يقم أصحابها بإضافة ملفات أنواع إليها (مثل lodash و express و react). هنا يتدخل المجتمع التقني العالمي عبر مستودع مفتوح المصدر يُدار بإشراف فريق TypeScript ويُسمى DefinitelyTyped. يتم نشر هذه التعريفات تحت مساحة الحزم @types على NPM، ويتم تثبيتها كاعتماديات تطوير (Dev Dependencies):
# تثبيت المكتبة الأصلية التنفيذية
npm install lodash
# تثبيت ملفات التصريح الخاصة بها من مجتمع DefinitelyTyped
npm install -D @types/lodash3. حزم قديمة أو داخلية تفتقر تماماً لملفات الأنواع
إذا قمت بتثبيت حزمة ووجدت أن الأمر npm i -D @types/my-package يعيد خطأ 404 Not Found، سيرفض TypeScript استيرادها وسيعرض الخطأ الشهير:
Could not find a declaration file for module 'my-package'. 'path/to/module.js' implicitly has an 'any' type.
لحل هذه المعضلة باحترافية، نلجأ إلى ما يُعرف بـ الوحدات النمطية المحيطة المؤقتة أو المخصصة (Custom Ambient Module Declarations)، وهو ما سنتناوله بالتفصيل في القسم التالي.
القسم 5: كتابة ملفات تصريح مخصصة للمكتبات الخارجية والأصول غير البرمجية
عندما تواجه حزمة تفتقر لملفات التصريح، أو عندما تحتاج لاستيراد ملفات صور أو أنماط CSS داخل مشروعك، تقوم بإنشاء ملف تعريفات محيطي مخصص، يُسمى عادة declarations.d.ts أو types/global.d.ts في جذر مجلد src.
الأسلوب السريع: التصريح الإجمالي (Shorthand Ambient Declaration)
إذا كنت بحاجة لاستخدام المكتبة فوراً ولا ترغب في كتابة تواقيع دقيقة لكافة دوالها في الوقت الحالي، يمكنك استخدام التصريح السريع. هذا يخبر TypeScript بأن المكتبة موجودة وأن كافة صادراتها تحمل النوع any مؤقتاً:
// src/types/untyped-libraries.d.ts
// تصريح سريع يسكت تحذيرات المترجم
declare module "untyped-legacy-slider";
declare module "custom-internal-analytics";الأسلوب المتقدم: التوصيف الهندسي الدقيق للحزمة الخارجية
للحصول على تجربة تطوير مثالية وأمان نوعي كامل، نكتب التوصيف الهيكلي للدوال والمعاملات التي نستخدمها فعلياً من تلك المكتبة:
// src/types/legacy-payment-gateway.d.ts
declare module "legacy-payment-gateway" {
export interface TransactionCustomer {
id: string;
fullName: string;
emailAddress: string;
}
export interface PaymentRequestPayload {
amountCents: number;
currency: "USD" | "EUR" | "SAR";
customer: TransactionCustomer;
idempotencyKey?: string;
}
export interface TransactionReceipt {
transactionId: string;
isSuccess: boolean;
authorizationCode: string;
settlementDate: string;
}
export class PaymentClient {
constructor(secretApiKey: string, isSandboxEnvironment?: boolean);
public charge(payload: PaymentRequestPayload): Promise<TransactionReceipt>;
public refund(transactionId: string, amountCents?: number): Promise<boolean>;
}
// تصدير دالة مساعدة عامة
export function verifyWebhookSignature(rawBody: string, signatureHeader: string): boolean;
}الآن، داخل أي ملف .ts في مشروعك، يمكنك استيراد هذه الحزمة كما لو كانت مبنية أصلاً بلغة TypeScript، وستحصل على فحص نوعي صارم للأخطاء وإكمال تلقائي فوري:
// src/services/checkoutService.ts
import { PaymentClient, PaymentRequestPayload } from "legacy-payment-gateway";
const client = new PaymentClient("SEC_LIVE_KEY_2026", false);
const payload: PaymentRequestPayload = {
amountCents: 5000,
currency: "USD",
customer: {
id: "CUST-902",
fullName: "محمد أحمد",
emailAddress: "mohammad@code-elta6ur.com"
}
};
client.charge(payload).then(receipt => {
console.log(`تم الدفع بنجاح. رقم العملية: ${receipt.transactionId}`);
});توصيف الأصول غير البرمجية (Non-code Assets: الصور، SVG، وCSS Modules)
في مشاريع الواجهات الأمامية الحديثة (مثل React وVue وNext.js)، نقوم باستيراد ملفات وسائط مثل الصور وملفات الستايل مباشرة داخل شفرة TypeScript. لكي لا يرمي المترجم خطأ بأن مسار الملف غير معرف، نقوم بتعريف قوالب الوحدات بالأنماط البرية (Wildcard Module Declarations):
// src/types/assets.d.ts
// توصيف ملفات الصور الثابتة كمسارات نصية
declare module "*.png" {
const assetPath: string;
export default assetPath;
}
declare module "*.jpg" {
const assetPath: string;
export default assetPath;
}
// توصيف ملفات الـ SVG التي قد تُستخدم كمسار نصي أو كمكون React
declare module "*.svg" {
import React = require("react");
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const srcPath: string;
export default srcPath;
}
// توصيف ملفات CSS Modules كقواميس كلاسات نصية
declare module "*.module.css" {
const classesDictionary: { readonly [className: string]: string };
export default classesDictionary;
}القسم 6: توسيع النطاق العام والوحدات النمطية القائمة (Module & Global Augmentation)
في كثير من السيناريوهات المتقدمة، لا نحتاج لتوصيف مكتبة جديدة بالكامل، بل نحتاج إلى تعديل أو توسيع كائنات ونطاقات موجودة بالفعل في النظام. على سبيل المثال: إضافة خاصية مخصصة إلى كائن window في المتصفح، أو إضافة كائن user إلى كائن الطلب Request في إطار عمل Express بعد التحقق من التوثيق. تُعرف هذه التقنية بـ Augmentation.
1. توسيع النطاق العام (Global Augmentation)
لإضافة خصائص مخصصة إلى كائنات المتصفح العامة مثل Window أو Document:
// src/types/window-extension.d.ts
// إخبار المترجم بتوسيع النطاق العالمي
export {}; // جعل الملف وحدة نمطية لتمكين declare global
declare global {
interface Window {
// إضافة إعدادات مخصصة لكائن النافذة
__CUSTOM_ANALYTICS_QUEUE__: Array<string>;
userAuthenticationToken?: string;
}
namespace NodeJS {
interface ProcessEnv {
// توسيع متغيرات البيئة بأسماء صريحة وأنواع مضمونة
DATABASE_URL: string;
JWT_SECRET_KEY: string;
APP_PORT: string;
}
}
}الآن، في أي مكان داخل تطبيقك، يمكنك كتابة window.__CUSTOM_ANALYTICS_QUEUE__.push(...) أو process.env.DATABASE_URL مع الاستفادة الكاملة من ميزة الإكمال التلقائي والتحقق الصارم من صحة الأسماء.
2. توسيع الوحدات الخارجية (Module Augmentation)
لنفترض أنك تستخدم إطار عمل Express في تطبيق الخادم، وتريد إضافة كائن المستخدم المصادق عليه currentUser إلى واجهة Request:
// src/types/express-custom.d.ts
import "express"; // استيراد الوحدة الأصلية أولاً لتفعيل خاصية التوسيع
declare module "express-serve-static-core" {
interface Request {
currentUser?: {
id: string;
username: string;
role: "ADMIN" | "EDITOR" | "SUBSCRIBER";
};
}
}بفضل ميزة دمج التصريحات (Declaration Merging)، سيقوم مترجم TypeScript بدمج الحقل currentUser بسلاسة داخل واجهة Request الأساسية، ولن تضطر لاستخدام التحايل غير الآمن مثل (req as any).currentUser.
القسم 7: دمج ملفات التصريح مع بيئات التطوير وإعدادات tsconfig.json
كيف يعرف محرر النصوص مثل Visual Studio Code أو WebStorm مكان ملفات التصريح وكيف يتأكد من تضمينها في عملية الفحص؟ يعتمد ذلك على إعدادات استراتيجية دقيقة داخل ملف tsconfig.json.
ضبط مسارات البحث عبر typeRoots و types
بشكل افتراضي، يبحث مترجم TypeScript عن ملفات التعريف داخل مجلد node_modules/@types تلقائياً. ولكن عندما تنشئ ملفات تصريح مخصصة داخل مشروعك، يجب توجيه المترجم لتضمينها عبر مصفوفة typeRoots أو مسار الملفات في include:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
/* تحديد مجلدات البحث عن ملفات التعريف */
"typeRoots": [
"./node_modules/@types", // الحزم المثبتة عبر npm
"./src/types" // مجلد التعريفات المخصصة الخاص بمشروعك
],
/* في حال أردت حصر التضمين لحزم محددة فقط لمنع تضخم الذاكرة */
// "types": ["node", "jest"],
"strict": true
},
"include": [
"src/**/*",
"src/types/**/*.d.ts" // التأكيد الصريح على قراءة ملفات التصريح
]
}التحقق من ملفات JavaScript عبر @ts-check و JSDoc
في المشاريع الهجينة (Hybrid Projects) التي تحتوي على ملفات .js إلى جانب ملفات .ts، يمكنك تفعيل فحص الأنواع الصارم على ملفات الـ JavaScript القديمة دون تحويلها إلى TypeScript بالكامل. يتم ذلك عبر وضع التعليق التوجيهي // @ts-check في أول سطر من ملف الـ JS، مع استخدام تعليقات JSDoc التي تشير إلى الأنواع المعرفة في ملفات .d.ts:
// legacyHelper.js
// @ts-check
/**
* @param {string} username - اسم المستخدم
* @param {number} retryAttempts - عدد المحاولات
* @returns {Promise<boolean>}
*/
async function authenticateUser(username, retryAttempts) {
if (typeof username !== "string") {
throw new Error("اسم المستخدم يجب أن يكون نصاً");
}
// سيوفر VS Code فحصاً نوعياً وإكمالاً تلقائياً هنا تماماً كما في ملفات TypeScript!
return retryAttempts > 0;
}
module.exports = { authenticateUser };القسم 8: نشر حزم NPM مع ملفات التصريح (Publishing Type-Safe NPM Packages)
إذا كنت تبني مكتبة مفتوحة المصدر أو حزمة برمجية لمشاركتها مع فريقك عبر NPM، فإن توفير ملفات التصريح هو المعيار الأساسي لجعل مكتبتك احترافية وسهلة الاستهلاك. يتم توثيق مسار ملف التصريح الرئيسي داخل ملف package.json في جذر الحزمة:
{
"name": "@code-elta6ur/core-math-utils",
"version": "1.0.0",
"description": "حزمة أدوات رياضية احترافية مدعومة بالكامل بأنواع TypeScript",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"typings": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"build": "tsc"
},
"devDependencies": {
"typescript": "^5.6.0"
}
}لاحظ استخدام الحقل "types" (أو الحقل البديل التوافقي "typings")، بالإضافة إلى تحديد مسارات الأنواع في الحقل الحديث "exports". هذا يضمن أنه عندما يقوم أي مطور بتثبيت حزمتك وكتابة import { ... } from "@code-elta6ur/core-math-utils"، سيتعرف محرره البرمجي فوراً على ملف index.d.ts ويبدأ بعرض التوثيق الذكي دون أي إعدادات إضافية.
القسم 9: أفضل الممارسات وحل المشكلات الشائعة (Troubleshooting)
التعامل مع ملفات التصريح يتطلب حذراً هندسياً لتفادي الوقوع في أخطاء تضارب الأسماء أو فقدان مسارات التحقق. نلخص فيما يلي أهم المشكلات العملية وطرق حلها الجذرية:
1. خطأ Duplicate Identifier والتصريحات المكررة
المشكلة: ظهور خطأ Duplicate identifier 'MyType' في المحرر، والذي يحدث غالباً عندما يتم تعريف نفس النوع في ملفين .d.ts مختلفين داخل المشروع، أو عندما تقوم حزمة خارجية وحزمة مخصصة بتعريف نفس الاسم في النطاق العام (Global Scope).
الحل: تأكد من عزل الأنواع داخل وحدات نمطية (Modules) باستخدام export و import بدلاً من تركها حرة في النطاق العام، أو استخدم مساحات الأسماء المحددة لتفادي التصادم في الذاكرة.
2. خطأ الشفرة التنفيذية داخل ملف التصريح
المشكلة: محاولة كتابة دالة تحتوي على منطق حسابي أو متغير بقيمة ابتدائية داخل ملف .d.ts (مثل export const x = 10; أو كتابة جسم دالة بداخل أقواس معقوفة). سيرمي المترجم فوراً الخطأ:
An implementation cannot be declared in ambient contexts.
الحل: احذف المنطق التنفيذي فوراً. في ملفات .d.ts، اكتب التواقيع فقط: export declare const x: number; أو export declare function doWork(): void;.
3. تسريع أداء المترجم عبر skipLibCheck
عندما يكبر حجم المشروع ويضم مئات الحزم من مستودع NPM، يقضي مترجم TypeScript وقتاً طويلاً في إعادة فحص كل ملف .d.ts موجود داخل مجلد node_modules للتأكد من خلوه من الأخطاء الداخلية. الحل القياسي في بيئات الإنتاج هو تفعيل خيار:
"skipLibCheck": trueهذا يوجه المترجم للتركيز فقط على فحص ملفات الكود المصدري الخاص بك، وتجاوز إعادة التحقق من صحة ملفات التعريف الخارجية، مما يقلل زمن التجميع والبناء بنسبة تصل إلى 60% في المشاريع الكبرى.
القسم 10: الأسئلة الشائعة وإجاباتها التفصيلية
1. هل يتم ترجمة ملفات .d.ts إلى ملفات .js عند بناء المشروع؟
لا، على الإطلاق. ملفات .d.ts لا تُترجم أبداً إلى JavaScript. وظيفتها بالكامل محصورة في مرحلة التطوير والترجمة (Compile Time) لتوجيه المترجم ومحرر النصوص. بمجرد انتهاء عملية البناء، تُحذف ولا يتبقى في بيئة التشغيل سوى ملفات .js الصرفة.
2. ما الفرق بين ملف .ts وملف .d.ts؟
ملف .ts هو ملف شفرة مصدرية كامل يحتوي على كود تنفيذي (دوال، فئات بحساباتها المنطقية) بالإضافة للأنواع، ويتم تجميعه إلى ملف .js مكافئ. أما ملف .d.ts فهو ملف تصريحي بحت يحتوي فقط على توصيفات الأنواع وتواقيع الدوال دون أي سطر برمجي تنفيذي ولا ينتج عنه أي ملف عند البناء.
3. كيف أتعامل مع مكتبة NPM تفتقر لملفات @types ولم أجد لها تعريفاً في أي مكان؟
أنشئ ملفاً باسم declarations.d.ts داخل مجلد مشروعك (مثلاً داخل src/types/)، وأضف بداخله السطر التالي: declare module "library-name";. هذا التصريح السريع سيخبر TypeScript بأن المكتبة موجودة وسيعامل كل صادراتها كنوع any مؤقتاً، مما يتيح لك استيرادها واستخدامها فوراً دون أن يوقف المترجم عملية البناء.
4. لماذا أحتاج إلى تفعيل declarationMap في مشروعي؟
خاصية "declarationMap": true تقوم بتوليد ملفات خرائط .d.ts.map تربط بين ملف التصريح الناتج وملف الكود المصدري الأصلي .ts. فائدتها الكبرى تظهر في بيئات التطوير متعددة الحزم (Monorepos)؛ فعندما يضغط المطور على F12 أو “Go to Definition” داخل المحرر، سينقله المحرر مباشرة إلى سطر الكود المصدري الأصلي .ts بدلاً من نقله لملف التصريح المجرد، مما يرفع إنتاجية التطوير بشكل ملحوظ.
الخلاصة والخطوات القادمة
في هذا الدرس المتقدم والشامل من دورة TypeScript من الصفر إلى الاحتراف (الدرس #21)، قمنا بتفكيك ملفات التصريح .d.ts من جذورها المعمارية. أدركنا أنها ليست ملفات JSON، بل هي نصوص TypeScript توصيفية مجردة تمثل العقد الأمني الذي يربط بين محرك الفحص البرمجي وعالم الـ JavaScript الخارجي.
تعلمنا كيف نوظف الكلمة المفتاحية declare، وكيف نولد ملفات التصريح تلقائياً عبر tsc، وكيف نستهلك حزم DefinitelyTyped، بالإضافة لكتابة توصيفات مخصصة للأصول غير البرمجية وتوسيع الكائنات العالمية مثل window و process.env باحترافية كاملة، وصولاً إلى إعداد حزمك للنشر على مستودع NPM وفق المعايير المعمارية العالمية.
في الدرس القادم، سننتقل إلى المرحلة التطبيقية المتقدمة التالية لنستكشف ملفات التكوين المتقدمة tsconfig.json، واستراتيجيات التحزيم عبر أدوات البناء الحديثة، وبناء مشاريع Monorepo ضخمة متوافقة كلياً مع نظام الأنواع في TypeScript.
المراجع والمصادر الرسمية المعتمدة:
- التوثيق الرسمي لـ TypeScript: مقدمة ملفات التصريح (Declaration Files Introduction)
- التوثيق الرسمي لـ TypeScript: قوالب كتابة ملفات .d.ts للمكتبات (Declaration Templates)
- مستودع DefinitelyTyped الرسمي على GitHub لتعريفات حزم NPM العالمية
- دورة TypeScript من الصفر إلى الاحتراف – منصة كود التطور
اكتشاف المزيد من كود التطور
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.
