كيفية استيراد JSON في TypeScript دون جنون
\n\nإذا سبق لك أن حاولت كتابة import data from './config.json' في TypeScript، فأنت تعرف هذا الشعور: المترجم يحمر وجهه، ويشتكي، ويطرح خطأ Cannot find module. ألم مألوف؟ بالتأكيد! سؤال استيراد JSON في TypeScript هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. وهذا ليس مفاجئًا: يُستخدم JSON في كل مكان — الإعدادات، التوطين، بيانات المحاكاة، القوائم الثابتة. لكن TypeScript افتراضيًا لا يعرف كيفية التعامل مع ملفات JSON.
في هذا البرنامج التعليمي، سنناقش جميع طرق استيراد JSON في TypeScript — من مجرد تفعيل علامة في tsconfig إلى الكتابة المتقدمة. ستتعلم كيف تجعل TypeScript صديقًا لـ JSON، ولن ترى هذا الخطأ الأحمر مرة أخرى. هيا بنا!
\n\nلماذا لا يرى TypeScript ملفات JSON؟
\nقبل الغوص في الكود، دعنا نفهم السبب. TypeScript هي طبقة فوق JavaScript تضيف الكتابة الثابتة. افتراضيًا، يتوقع مترجم TypeScript أن جميع الوحدات المستوردة هي ملفات .ts أو .js. JSON ليس وحدة، بل هو تنسيق بيانات. TypeScript ببساطة لا يعرف كيفية تفسيره.
\nالحل يكمن في مستويين:
\n- \n
- إعداد المترجم — تفعيل دعم JSON عبر العلامة
resolveJsonModule. \n - إعلان الوحدة — وصف النوع يدويًا لملفات JSON، إذا كانت العلامة غير مناسبة. \n
الطريقة 1: تفعيل resolveJsonModule (الطريق الصحيح)
\nأبسط وأفضل طريقة هي إضافة الخيار resolveJsonModule إلى tsconfig.json. هذه علامة تخبر TypeScript: "مرحبًا يا صديقي، دعنا نستورد JSON كوحدات عادية".
// tsconfig.json\n{\n "compilerOptions": {\n "resolveJsonModule": true,\n "esModuleInterop": true\n }\n}\nبعد ذلك، يمكنك بكل سهولة كتابة:
\n// config.ts\nimport config from './config.json';\n\nconsole.log(config.apiUrl); // يعمل!\nconsole.log(config.port); // يعمل!\nماذا يحدث هنا؟ يقوم TypeScript تلقائيًا بإنشاء أنواع لملف JSON المستورد. إذا كان في JSON الخاص بك حقل apiUrl: string و port: number، فسيستنتج TypeScript أنواعها ويتحقق من الاستخدام. رائع، أليس كذلك؟
لكن هناك فارق بسيط: resolveJsonModule يتطلب أيضًا تفعيل esModuleInterop أو allowSyntheticDefaultImports لكي يعمل الاستيراد الافتراضي بشكل صحيح. بدون ذلك، ستحصل على خطأ عند محاولة الاستيراد.
الطريقة 2: الاستيراد مع التصديرات المسماة
\nأحيانًا لا تحتاج إلى ملف JSON بأكمله، بل فقط إلى حقول معينة. TypeScript يدعم هذا أيضًا:
\nimport { apiUrl, port } from './config.json';\n\nconsole.log(apiUrl); // نص\nconsole.log(port); // رقم\nهذا ممكن بفضل ما يسمى "tree-shaking" في أدوات التجميع (Webpack, Vite)، ولكن على مستوى TypeScript هو مجرد تفكيك للكائن. ومع ذلك، تذكر: إذا كنت تستخدم resolveJsonModule، فإن TypeScript ينشئ تلقائيًا أنواعًا لجميع الحقول، لذا يمكنك استيراد الكائن بأكمله أو أجزاء منه بثقة.
الطريقة 3: require بدلاً من import (للمشاريع القديمة)
\nإذا كنت تعمل في مشروع لا يمكن فيه تفعيل resolveJsonModule لسبب ما (مثل تعارض مع إعدادات أخرى)، يمكنك استخدام require القديم الجيد:
const config = require('./config.json');\n\nconsole.log(config.apiUrl); // يعمل، لكن بدون أنواع\nمشكلة هذا النهج واضحة: تفقد الكتابة (Typing). TypeScript لا يعرف ما بداخل config، وسيعتبر نوعه any. وهذا يفتح الباب للأخطاء. إذا كنت تستخدم require، فعلى الأقل أضف إعلان النوع:
interface Config {\n apiUrl: string;\n port: number;