لا يمكن تشغيل ملف TypeScript كما هو، لأن المتصفحات ومحركات JavaScript لا تفهم تعليقات الأنواع. يجب أن يحذف شيء ما الأنواع أولًا. هذا الشيء إما مترجم TypeScript (tsc)، الذي يفحص الأنواع أيضًا، أو أداة أسرع تكتفي بحذفها. أسرع طريقة لتشغيل الكود في هذه الصفحة هي زر Run:
الناتج:
[x] Install TypeScript
[ ] Run a .ts file
كل مثال قابل للتشغيل في هذا التوثيق يعمل بالطريقة نفسها: تفحص TypeScript 7 أنواع الكود مع تفعيل strict، ولا يعمل إلا إذا لم تكن فيه أخطاء أنواع. وللتجارب الأطول، ساحة TypeScript التجريبية هي المحرر نفسه في صفحة مستقلة. بقية هذه الصفحة عن تشغيل ملفات .ts على جهازك.
الخيارات في لمحة
| الأمر | يفحص الأنواع | يحتاج إلى خطوة بناء | يدعم enum وnamespace وخصائص المعاملات |
|---|---|---|---|
npx tsc ثم node dist/index.js | نعم | نعم | نعم |
node index.ts (Node.js 22.18+ و23.6+) | لا | لا | لا |
npx tsx index.ts | لا | لا | نعم |
npx ts-node index.ts | نعم | لا | نعم، لكن ليس مع TypeScript 7 |
deno run index.ts | لا (يفحصها deno check) | لا | نعم |
bun index.ts | لا | لا | نعم |
العمود الذي يفاجئ الناس هو الأول: معظم الخيارات السريعة تشغّل كودًا فيه أخطاء أنواع. المشروع النموذجي يشغّل الكود بواحد منها، ويشغّل tsc --noEmit منفصلًا، في المحرر وفي CI، لاكتشاف الأخطاء.
الترجمة بـ tsc ثم التشغيل بـ Node
هذه الطريقة تعمل في كل مكان وتفحص كل شيء. مع تثبيت TypeScript في المشروع وملف tsconfig.json يضبط "rootDir": "./src" و"outDir": "./dist":
npx tsc
node dist/index.js
يفحص tsc أنواع كل الملفات، ثم يكتب ملفات .js في dist. ولملف واحد دون مشروع، مرّر اسم الملف. عندها يستخدم الخيارات الافتراضية ويكتب index.js بجانب index.ts:
npx tsc index.ts
node index.js
(إذا كان في المجلد ملف tsconfig.json، يرفض tsc أسماء الملفات بالخطأ error TS5112؛ شغّل npx tsc وحده، أو أضف --ignoreConfig.)
افتراضيًا يكتب tsc كود JavaScript حتى عند وجود أخطاء أنواع، لذلك يستطيع node تشغيل برنامج فشل في الفحص. أضف "noEmitOnError": true إلى الإعدادات لمنع ذلك، أو اربط الأمرين في سكربت بحيث لا تعمل الخطوة الثانية إلا إذا نجحت الأولى:
{
"scripts": {
"build": "tsc",
"start": "tsc && node dist/index.js"
}
}
وأثناء التطوير، يعيد npx tsc --watch الترجمة عند كل حفظ.
تشغيل TypeScript مباشرة بـ Node.js
يشغّل Node.js الحالي ملفات .ts بنفسه:
node index.ts
يحذف Node تعليقات الأنواع، ويستبدلها بمسافات بيضاء حتى تبقى أرقام الأسطر في تتبع الأخطاء مطابقة، ثم يشغّل ما تبقى. هذه الميزة مفعّلة افتراضيًا منذ Node.js 23.6.0 و22.18.0، ولا تطبع أي تحذير منذ 24.3.0 و22.18.0، وأصبحت مستقرة في Node.js 24.12.0 و25.2.0. الإصدارات الأقدم التي تحتوي على الميزة (من 22.6 إلى 22.17، ومن 23.0 إلى 23.5) تحتاج إلى الخيار: node --experimental-strip-types index.ts.
تأتي معها أربع قواعد:
- لا فحص للأنواع. ملف فيه
const age: number = "forty"يعمل ويطبعforty. - الصياغة القابلة للمحو فقط. كل ما يجب أن يتحول إلى كود JavaScript بدل أن يختفي يُرفض:
enum، وكتلnamespaceالتي تحتوي على كود تشغيلي، وخصائص المعاملات في المُنشئ مثلconstructor(private name: string)، والأسماء المستعارةimport x = require(). يتوقف Node بالخطأSyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode. - يُتجاهل
tsconfig.json. خيارات مثلpathsأوtargetلا أثر لها. - الاستيرادات تحتاج إلى أسماء ملفات حقيقية. اكتب
import { add } from "./math.ts"مع الامتداد، وعلّم الاستيرادات الخاصة بالأنواع فقط بـtype:import { add, type Pair } from "./math.ts". دونtypeيبحث Node عن تصدير تشغيلي اسمهPairويفشل بالخطأSyntaxError: The requested module './math.ts' does not provide an export named 'Pair'.
يوجد خياران في المترجم يجعلان tsc يفرض القواعد نفسها، فيحذرك المحرر قبل Node: "erasableSyntaxOnly": true يبلّغ عن error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. عند وجود enum، و"verbatimModuleSyntax": true يشترط الكلمة type في الاستيرادات الخاصة بالأنواع فقط. ولمواصلة كتابة امتداد .ts في الاستيرادات مع الترجمة بـ tsc، أضف "rewriteRelativeImportExtensions": true، الذي يحوّل ./math.ts إلى ./math.js في الناتج.
في Node.js 24 يوجد أيضًا --experimental-transform-types، الذي يولّد كودًا لـ enum وخصائص المعاملات بدل رفضها. يطبع ExperimentalWarning، وقد أزال Node.js 26 هذا الخيار، فلا تبنِ عليه.
يستخدم هذا المثال ميزتين يرفضهما node index.ts. يعمل هنا لأن المحرر يترجمه بمترجم TypeScript، الذي يولّد JavaScript لكلتيهما:
النسخة القابلة للمحو من الكود نفسه تستخدم كائن const وحقلًا عاديًا، ويستطيع Node تشغيلها كما هي:
tsx
يشغّل tsx ملف TypeScript بخطوة واحدة، دون إعداد ودون قيود على الصياغة:
npm install --save-dev tsx
npx tsx index.ts
npx tsx watch index.ts # rerun on every change
يحوّل الكود باستخدام esbuild، لذلك تعمل enum وnamespace وخصائص المعاملات، وتُحل الاستيرادات دون امتداد كما تُحل في أداة تجميع. ومثل حذف الأنواع في Node، لا يفحص الأنواع. إنه الخيار الشائع للسكربتات وخوادم التطوير والاختبارات على إصدارات Node.js الأقدم من ميزة حذف الأنواع، أو عندما يستخدم الكود صياغة يرفضها Node.
ts-node
كان ts-node لسنوات الطريقة المعيارية لتشغيل TypeScript على Node.js، وما زالت كثير من الدروس والمشاريع القديمة تستخدمه (npx ts-node index.ts وnode -r ts-node/register). يفحص الأنواع افتراضيًا باستخدام واجهة JavaScript البرمجية لمترجم TypeScript.
وهذه الواجهة تحديدًا هي ما لا تشحنه TypeScript 7: مترجمها برنامج أصلي، وحزمة typescript 7 لا تكشف أي واجهة برمجية للمترجم لـ JavaScript. مع تثبيت TypeScript 7 ينهار ts-node قبل تشغيل أي شيء:
TypeError: Cannot read properties of undefined (reading 'fileExists')
at readConfig (/project/node_modules/ts-node/dist/configuration.js:91:33)
يعود آخر إصدار من ts-node، وهو 10.9.2، إلى ديسمبر 2023. في الكود الجديد استخدم tsx أو node index.ts. والإعداد القائم الذي يعتمد على ts-node يستمر في العمل إذا بقي المشروع على TypeScript 6 (npm install --save-dev typescript@6) وكان فيه ملف tsconfig.json، ولو كان فارغًا {}. دونه يعود ts-node إلى إعدادات افتراضية مدمجة تتضمن تحليل الوحدات node10 الذي أهملته TypeScript 6، فينتهي npx ts-node index.ts دون تشغيل الملف ودون طباعة أي خطأ.
Deno وBun
تتعامل بيئتا التشغيل كلتاهما مع TypeScript كنوع ملفات من الدرجة الأولى:
deno run index.ts # runs without checking
deno check index.ts # type-checks, reports errors, runs nothing
bun index.ts # runs without checking
لا تحتاج أي منهما إلى تثبيت typescript ولا إلى tsconfig.json، وكلتاهما تدعم enum وبقية الميزات غير القابلة للمحو. يشحن Deno نسخته الخاصة من مترجم TypeScript لـ deno check. أما Bun فيحذف الأنواع فقط، لذلك تثبّت في مشروع Bun حزمة typescript وتشغّل tsc --noEmit للعثور على أخطاء الأنواع.
أخطاء الأنواع لا توقف البرنامج إلا مع tsc
الطرق التي تشغّل tsc أولًا هي وحدها التي ترفض تشغيل برنامج فيه أخطاء أنواع. المحرر في هذه الصفحة واحد منها، لذلك يتوقف هذا المثال عند المترجم:
index.ts(6,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
إذا حُفظ الكود نفسه كملف وشُغّل بـ node index.ts أو npx tsx index.ts أو bun index.ts، فإنه يعمل ويطبع 12، لأن 3 * "4" يحوّل النص إلى رقم. ولهذا السبب يجب إبقاء tsc --noEmit ضمن سير العمل حتى عندما تشغّل أداة أسرع الكود:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"typecheck": "tsc --noEmit"
}
}
أيها تستخدم؟
- للتعلم أو لاختبار سريع: زر Run في هذه الصفحات، أو الساحة التجريبية.
- لسكربت أو أداة صغيرة على Node.js حديث:
node index.ts، معerasableSyntaxOnlyفي الإعدادات حتى يعلّم المحرر كل ما سيرفضه Node. - لأي مشروع Node.js وبأي صياغة:
tsxللتشغيل، وtsc --noEmitللفحص. - لمكتبة أو لأي شيء تنشره:
tsc، لأنه يكتب أيضًا ملفات.d.tsالتي يحتاج إليها مستخدموك. - لكود الواجهة الأمامية: أداة التجميع أو إطار العمل (Vite أو Next.js أو Angular CLI) يشغّل TypeScript لك؛ أضف
tsc --noEmitللفحص.
الأسئلة الشائعة
كيف أشغّل ملف TypeScript؟
الطريقة التقليدية خطوتان: npx tsc يترجم .ts إلى .js، ثم node dist/index.js يشغّل الناتج. على Node.js 22.18 أو 23.6 وما بعدهما يمكنك أيضًا تشغيل node index.ts مباشرة، ما دام الملف لا يستخدم إلا صياغة أنواع قابلة للمحو. ويشغّل npx tsx index.ts أي ملف TypeScript بخطوة واحدة.
هل يستطيع Node.js تشغيل TypeScript مباشرة؟
نعم. منذ Node.js 23.6 و22.18 يعمل node file.ts دون خيارات: يحذف Node تعليقات الأنواع ويشغّل الباقي. لا يفحص الأنواع، ويتجاهل tsconfig.json، ويرفض الصياغة التي تحتاج إلى توليد كود، مثل enum وnamespace الذي يحتوي على كود تشغيلي وخصائص المعاملات في المُنشئ.
هل يعمل ts-node مع TypeScript 7؟
لا. يستدعي ts-node واجهة JavaScript البرمجية للمترجم، وحزمة typescript 7 لا توفرها، لذلك ينهار عند البدء (Cannot read properties of undefined (reading 'fileExists')). آخر إصدار له هو 10.9.2 من ديسمبر 2023. استخدم tsx أو حذف الأنواع المدمج في Node، أو أبقِ ts-node مع TypeScript 6.
ما الفرق بين tsx و ts-node؟
يحذف tsx الأنواع فقط (باستخدام esbuild) ويشغّل الناتج، لذلك يبدأ بسرعة ولا يبلّغ أبدًا عن أخطاء الأنواع. أما ts-node فيفحص الأنواع افتراضيًا باستخدام مترجم TypeScript، ما يجعله أبطأ ويربطه بواجهة JavaScript البرمجية للمترجم. معظم المشاريع اليوم تجمع بين tsx أو node file.ts للتشغيل وtsc --noEmit للفحص.
هل توجد بيئة TypeScript تجريبية على الإنترنت؟
نعم. أمثلة الكود في صفحات التوثيق هذه وساحة TypeScript التجريبية على Coddy تترجم كودك بـ TypeScript 7 وتشغّله، وتعرض أخطاء المترجم أو ناتج البرنامج. وتعرض TypeScript Playground الرسمية على typescriptlang.org كود JavaScript الناتج والأخطاء.