TypeScript: شرح مفصل لملف tsconfig.json في TypeScript
آخر تحديث: 2026-08-26
يُعد ملف tsconfig.json مركز التكوين لمشاريع TypeScript — فهو يحدد للمترجم كيفية ترجمة الكود، والتحقق من الأنواع، وإخراج النتائج. ويُعد فهم خيارات التكوين هذه أمرًا ضروريًا لضمان سير مشروع TypeScript الخاص بك بسلاسة.
1. أساسيات ملف tsconfig.json
(1) إنشاء ملف تكوين
BASH
# Automatically Generate Default Configuration
tsc --init
# Generate a detailed configuration with comments
tsc --init --typescript
(2) الهيكل الأساسي
JSON
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
(3) الحقول ذات المستوى الأعلى
| الحقل | الوصف |
|---|---|
compilerOptions |
خيارات المُترجم |
include |
الملفات المضمنة (وضع glob) |
exclude |
الملفات المستبعدة |
files |
قائمة الملفات المحددة صراحةً |
references |
مراجع المشروع (مستودع واحد) |
extends |
التوريث من ملف تكوين آخر |
2. خيارات التجميع الأساسية
(1) الهدف — هدف التجميع
حدد إصدار جافا سكريبت المُجمَّع:
JSON
{
"compilerOptions": {
"target": "ES2020"
}
}
| القيمة | الوصف | السيناريوهات الموصى بها |
|---|---|---|
"ES5" |
متوافق مع المتصفحات القديمة | يدعم IE11 |
"ES2018" |
المتصفحات الحديثة | مشاريع الويب العامة |
"ES2020" |
أحدث الميزات في الإصدار المستقر | موصى به |
"ESNext" |
أحدث ميزات المقترحات | مشاريع رائدة |
💡 نصيحة: لا يؤثر الخيار
target إلا على تحويل الصيغة (مثل: الدوال السهمية → الدوال العادية)؛ ولا يؤثر على فحص الأنواع. يتم التحكم في فحص الأنواع بواسطة الخيار lib.
(2) الوحدة — نظام الوحدات
JSON
{
"compilerOptions": {
"module": "ESNext"
}
}
| القيمة | الوصف | السيناريوهات الموصى بها |
|---|---|---|
"CommonJS" |
الإعدادات الافتراضية لـ Node.js | مشروع Node |
"ESNext" / "ES2015" |
وحدات ES | متصفح/Deno/Vite |
"UMD" |
الوحدات النمطية متعددة الأغراض | إصدارات المكتبة |
"System" |
SystemJS | مُحمِّل الوحدات النمطية القديم |
(3) moduleResolution — استراتيجية تحديد دقة الوحدة النمطية
JSON
{
"compilerOptions": {
"moduleResolution": "node"
}
}
| القيمة | الوصف |
|---|---|
"node" |
نمط Node.js (موصى به) |
"classic" |
النمط القديم لـ TS (غير موصى به) |
"bundler" |
Vite/esbuild وأدوات البناء الأخرى (TS 5.0+) |
(4) lib — مكتبة الأنواع
حدد إعلانات الأنواع المدمجة المتاحة:
JSON
{
"compilerOptions": {
"lib": ["ES2020", "DOM", "DOM.Iterable"]
}
}
| القيمة | النوع المُقدَّم |
|---|---|
"ES2020" |
Promise، Array.flat، BigInt، إلخ. |
"DOM" |
المستند، النافذة، HTMLElement، إلخ. |
"DOM.Iterable" |
NodeList 's for...of |
"ES2020.String" |
ES2020: طرق معالجة السلاسل |
"ES2020.Promise" |
Promise.allSettled، وما إلى ذلك |
💡 نصيحة: يتم تضمين
target تلقائيًا مع lib المقابل. إذا قمت بتحديد lib صراحةً، فلن يتم تضمينه تلقائيًا بعد ذلك — وستحتاج إلى إدراج جميع المكتبات المطلوبة يدويًّا. عادةً ما تتطلب مشاريع الويب ["ES2020", "DOM"].
(5) outDir و rootDir
JSON
{
"compilerOptions": {
"outDir": "./dist", // Compilation Output Directory
"rootDir": "./src", // Source Code Root Directory(Preserve the directory structure)
"declaration": true, // Generate .d.ts Statement
"sourceMap": true // Generate .js.map Source Code Mapping
}
}
3. خيار «الوضع الصارم»
(1) تم تمكين الوضع الصارم بالكامل
JSON
{
"compilerOptions": {
"strict": true
}
}
strict: true يعادل تفعيل جميع الخيارات التالية في آن واحد:
| الخيار | الوصف |
|---|---|
strictNullChecks |
لا يمكن تعيين القيمة «فارغ/غير معرّف» إلى أنواع أخرى |
strictFunctionTypes |
الفحص العكسي لمعلمات الدالة |
strictBindCallApply |
الفحص الدقيق لـ bind/call/apply |
strictPropertyInitialization |
يجب تهيئة خصائص الفئة |
noImplicitAny |
غير صريح any محظور |
noImplicitThis |
عدم السماح باستخدام «this» الضمني كـ «any» |
alwaysStrict |
إصدار "use strict" |
(2) فهم كل نقطة
TYPESCRIPT
// strictNullChecks: true
let name: string = null; // ❌ null Cannot be assigned string
let name2: string | null = null; // ✅ Explicit Declaration
// noImplicitAny: true
function greet(name) { // ❌ The parameter is implicitly set to any
return name;
}
function greet2(name: string) { // ✅ Explicit Annotation
return name;
}
// strictPropertyInitialization: true
class User {
name: string; // ❌ Property not initialized
age: number = 0; // ✅ Has an initial value
}
📌 توصية: قم بتمكين
strict لجميع المشاريع الجديدة. فهو حجر الزاوية في أمان الأنواع في TypeScript — ورغم أن إضافة تعليقات الأنواع قد تتطلب مجهودًا إضافيًا في البداية، إلا أنها تساعد في منع عدد كبير من أخطاء وقت التشغيل.
▶ مثال: مقارنة بين الوضع الصارم وما قبله وما بعده
TYPESCRIPT
// strict: false — the following code does not generate any errors, but it may crash during execution.
let name: string = null as any; // Runtime name.toUpperCase() Breakdown
function greet(user) { // user Implicit any
return user.name; // No type checking
}
// strict: true — captured at compile time
let name2: string | null = null; // ✅ Must be explicitly declared null
function greet2(user: { name: string }) { // ✅ Parameters must be labeled
return user.name;
}
الناتج:
TEXT
📖 للعرض فقط
// Executed successfully
4. تكوين الوحدات والمسارات
(1) تعيين المسار
JSON
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"],
"@components/*": ["src/components/*"]
}
}
}
(2) resolveJsonModule
JSON
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true
}
}
TYPESCRIPT
// Import Allowed JSON Documents
import config from "./config.json";
console.log(config.port); // ✅
(3) allowJs مع checkJs
JSON
{
"compilerOptions": {
"allowJs": true, // Allow compilation JS Documents
"checkJs": false // Do not check JS File Type(Compile Only)
}
}
💡 الغرض: عند ترحيل مشروع JS إلى TS تدريجيًّا، ابدأ بتمكين
allowJs للسماح بتعايش TS وJS، ثم أضف الأنواع تدريجيًّا.
5. خيارات جودة الكود
JSON
{
"compilerOptions": {
"noUnusedLocals": true, // Error: Unused local variables
"noUnusedParameters": true, // Error: Unused function parameters
"noImplicitReturns": true, // Error: Function branch does not return a value
"noFallthroughCasesInSwitch": true, // Error: switch fallthrough
"forceConsistentCasingInFileNames": true // File names must be case-sensitive
}
}
(1) عرض توضيحي
TYPESCRIPT
// noUnusedLocals: true
let unused = 42; // ❌ Unused variables
// noUnusedParameters: true
function handler(event: Event) { // ❌ event Unused
console.log("Trigger");
}
// Fix: Use _ prefix tag
function handler2(_event: Event) { // ✅ _ The prefix does not cause an error
console.log("Trigger");
}
// noImplicitReturns: true
function getGrade(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
// ❌ Missing else Branched return
}
// noFallthroughCasesInSwitch: true
switch (action) {
case "create":
createItem();
// ❌ Missing break——case Penetration
case "update":
updateItem();
break;
}
6. قوالب التكوين الشائعة
(1) مشروع الخلفية باستخدام Node.js
JSON
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
(2) مشروع واجهة مستخدم باستخدام React (Vite)
JSON
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
(3) مشاريع المكتبات (نشر حزم npm)
JSON
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"declarationDir": "./dist/types",
"outDir": "./dist/esm",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
▶ مثال: تأثيرات تكوين target وmodule
TYPESCRIPT
// The same source code compiles differently based on target/module settings
async function fetchData(): Promise<string> {
let response = await Promise.resolve("hello");
return response.toUpperCase();
}
export function greet(name: string): string {
return `Hello, ${name}!`;
}
الناتج:
TEXT
📖 للعرض فقط
Compilation output varies by target/module — see explanations below
With "target": "ES5", async/await compiles to a verbose state machine;
with "target": "ES2020", it stays as native async/await.
With "module": "CommonJS", exports become exports.greet = greet;
with "module": "ESNext", they remain as export function greet.
▶ مثال: التحقق الصارم من القيم الخالية في الممارسة العملية
TYPESCRIPT
// strictNullChecks: true prevents common null bugs
interface User { name: string; email: string | null; }
function getDisplayName(user: User): string {
// return user.email.toLowerCase(); // ❌ Object is possibly null
return user.email ? user.email.toLowerCase() : user.name; // ✅
}
function findUser(id: number): User | null {
return id > 0 ? { name: "Alice", email: "a@b.com" } : null;
}
let user = findUser(1);
// console.log(user.name); // ❌ user is possibly null
if (user) {
console.log(user.name); // ✅ narrowed to User
}
الناتج:
TEXT
📖 للعرض فقط
Alice
❓ أسئلة شائعة
س هل تجعل
strict كتابة الكود أكثر صعوبة؟ج قد تتطلب في البداية المزيد من تعليقات الأنواع (خاصةً لفحوصات القيمة الفارغة)، ولكن على المدى الطويل، فإنها تقلل بشكل كبير من الأخطاء التي تحدث أثناء التشغيل. نوصي بتمكين
strict منذ البداية — فبمجرد أن تعتاد عليها، ستجد في الواقع أنه من غير المريح عدم استخدامها. إذا كان مشروعك كبيرًا بالفعل، فيمكنك تمكينه تدريجيًا: قم أولًا بتمكين noImplicitAny، ثم strictNullChecks، وأخيرًا قم بتمكين strict بالكامل.س ما هو noEmit؟ ولماذا تم إنشاء مشروع Vite؟
ج
noEmit: true يسمح لـ TypeScript بإجراء فحص الأنواع فقط دون إنتاج ملفات JS. يستخدم مشروع Vite أداة Vite (esbuild) للتحويل البرمجي والتجميع، بينما يقتصر دور tsc على فحص الأنواع فقط — لذا لا داعي لأن يقوم tsc بإنتاج ملفات. استخدم tsc --noEmit للتحقق من الأنواع في CI، ودع Vite يتولى التجميع في الوقت الفعلي أثناء التطوير.س هل ينبغي تمكين skipLibCheck؟
ج نوصي بتمكينه. تعمل ميزة skipLibCheck على تخطي فحص الأنواع لملفات
.d.ts، مما قد يؤدي إلى تسريع عملية الترجمة بشكل ملحوظ. الجانب السلبي هو أنه قد يتجاهل أخطاء في إعلانات الأنواع الخاصة بأطراف ثالثة — لكن المخاطرة منخفضة للغاية (حزمة @types تخضع لمراجعة المجتمع). يمكن أن يؤدي تمكين skipLibCheck في المشاريع الكبيرة إلى توفير 30% أو أكثر من وقت الترجمة.س ما الغرض من استخدام
extends لتوريث التكوين؟ج عندما يحتوي المشروع على عدة ملفات
tsconfig (مثل الواجهة الأمامية، ونصوص Node، والاختبارات)، استخدم extends لمشاركة التكوين الأساسي وتجاوز الاختلافات فقط. يمكن لـ tsconfig.node.json أن extends tsconfig.json، مع تعديل الخيارات مثل target وmodule فقط. وهذا يتجنب تكرار التكوين.📖 ملخص
tsconfig.jsonهو مركز التكوين لمشاريع TypeScript — ويحتوي على ثلاثة حقول أساسية:compilerOptionsوincludeوexcludetargetيتحكم في إصدار JavaScript، وmoduleيتحكم في نظام الوحدات النمطية، وlibيتحكم في مكتبات الأنواع المتاحةstrict: trueتمكين جميع عمليات الفحص الصارمة — يجب تمكينها للمشاريع الجديدة- تعتمد عملية تعيين المسارات (baseUrl + paths) على استخدام الأسماء المستعارة لاستبدال المسارات المطلقة الطويلة
- تم تحسين خيارات جودة الكود (مثل noUnusedLocals وnoImplicitReturns) بشكل أكبر
- تختلف قوالب التكوين الموصى بها باختلاف أنواع المشاريع — مشاريع الخلفية التي تستخدم Node، ومشاريع الواجهة الأمامية التي تستخدم React، ومشاريع المكتبات
📝 تمارين
- تمرين أساسي (مستوى الصعوبة ⭐): استخدم
tsc --initلإنشاء ملفtsconfig.jsonالافتراضي، وقم بتغييرtargetإلى ES2020، وقم بتمكينstrict، واضبطoutDirعلىdist. أنشئ ملف TypeScript بسيطًا، وقم بتجميعه، وتأكد من أنه يعمل. - تمرين متقدم (مستوى الصعوبة ⭐⭐): قم بتكوين ملف
tsconfig.jsonيدعم الاسم المستعار للمسار@/*→src/*. أنشئsrc/utils/math.tsوsrc/main.ts، واستخدم الاسم المستعار لاستيراد الدوال منmath.tsإلىmain.ts. - التحدي (مستوى الصعوبة: ⭐⭐⭐): صمم تسلسلاً هرميًا للتكوين لمشروع أحادي المستودع — الأساسي
tsconfig.base.json(خيارات مشتركة)، وpackages/app/tsconfig.json(يمتد من الأساسي، واجهة مستخدم React)، وpackages/server/tsconfig.json(يمتد من الأساسي، الخلفية Node) — واستخدمreferencesلربط المشروعين الفرعيين.