تعليمات الشرطات المائلة الثلاث في TypeScript
مقدمة
تعليمات الشرطات المائلة الثلاث (Triple-slash directives) هي تعليقات تكتب في سطر واحد تحتوي على وسم XML واحد. تُستخدَم محتويات التعليق كتعليمات (إرشادات) للمترجم.
تكون تعليمات الشرطات المائلة الثلاث صالحةً فقط في أعلى الملفّ الذي تكون هذه التعليمات موجودة داخله. ويُمكن لهذه التعليمات أن تُسبَق فقط بتعليق في سطر واحد أو تعليق متعدّد الأسطر (multi-line comment)، ما يشمل تعليمات شرطات مائلة ثلاث أخرى. إذا وُجِدَت بعد جملة أو تصريح فستُعامَل على أنها تعليقات عادية في سطر واحد (regular single-line comments)، ولا يكون لها حينئذٍ أي معنًى خاص.
/// <reference path="..." />
تعليمة /// <reference path="..." />
أشهر تعليمة في TypeScript. وتعمل كتصريح اعتمادية (dependency) بين الملفات.
تُعلِم إحالات (references) الشرطات الثلاث المترجمَ بشَمْلِ (include) ملفات إضافية في عملية الترجمة.
وهي كذلك طريقة لترتيب المُخرَج عند استخدام الخيار --out
أو الخيار --outFile
. تُخرَج الملفّات إلى مكان الملفّ المُخرَج بنفس ترتيب المدخل بعد عملية المعالجة القَبْليّة (preprocessing).
المعالجة القبلية للملفات المُدخلَة (Preprocessing input files)
يؤدي المترجم عملية معالجة قبلية على الملفات المدخلة لتقرير (resolve) جميع تعليمات الشرطات الثلاث. تُضاف ملفّات إضافية إلى الترجمة أثناء هذه العملية.
تبدأ العملية بمجموعة من ملفات الجذر (root files)؛ وهي أسماء الملفات التي تُحدّد على سطر الأوامر أو في قائمة "files"
داخل ملفّ tsconfig.json
. تُعالَج ملفات الجذر هذه قبليًّا بنفس الترتيب الذي حُدِّدت فيه. تُعالَج جميع إحالات الشرطات الثلاث الموجودة في ملفٍّ قبل إضافته إلى القائمة، ما يشمل كذلك معالجة أهداف الإحالات. تُقرَّر إحالات الشرطات الثلاث بآلية العمق أولًا ( depth first manner) حسب ترتيبها في الملفّ.
يُقرَّر مسار (path) الإحالة نسبةً (relative) إلى الملفّ الذي يحتوي على تعليمة الشرطات الثلاث، هذا إن لم يكن الملفُّ ملفَّ جذرٍ.
الأخطاء
تُعَدّ إحالة ملفٍّ غير موجودٍ خطأً. ومن الخطأ كذلك إحالة ملفٍّ إلى نفسه.
استخدام --noResolve
إذا حُدِّد خيار المترجم --noResolve
، فستُتَجاهَل إحالات الشرطات الثلاث؛ ولن تكون نتيجتها لا إضافة ملفّات جديدة ولا تغيير ترتيب الملفّات المتوفّرة.
/// <reference types="..." />
هذه التعليمة مشابهة لتعليمة /// <reference path="..." />
، لأنّها تعمل كتصريح عن اعتماديةٍ؛ لكن تعليمات /// <reference types="..." />
تصرِّح عن الاعتماد على حزمة (package).
عمليّة تقرير أسماء الحزم هذه مشابهة لآلية تقرير أسماء الوحدات في جملة import
. يُمكن القول بأنّ تعليمات /// <reference types="..." />
بمثابة طريقة لاستيراد حزم التصريحات (declaration packages) كما تستورد جملة import
الوحدات.
على سبيل المثال، استخدام التعليمة /// <reference types="node" />
في ملف تصريحاتٍ (declaration file) يصرّحُ بأنّ هذا الملفّ يستخدم أسماءً معرّفة في @types/node/index.d.ts
؛ وبالتالي فهذه الحزمة تحتاج إلى أن تُشمَل في الترجمة مع ملفّ التصريحات.
اِستخدم هذه التعليمات فقط عندما تكتب ملفّ d.ts
يدويًّا.
بالنسبة لملفات التصريحات التي تولّد أثناء الترجمة، فإنّ المترجم يُضيف تلقائيّا إحالات /// <reference types="..." />
عوضًا عنك؛ تُضاف تعليمة /// <reference types="..." />
إلى ملف تصريحات مولَّد إذا وفقط إذا كان الملف الناتج يستخدم أي تصريحات من الحزمة المُحالة.
إن أردت التصريح عن اعتماديّةٍ على حزمة @types
في ملفّ .ts
، فاستخدم الخيار --types
على سطر الأوامر أو في ملفّ tsconfig.json
الخاص بك. انظر توثيق استخدام @types
، وtypeRoots
، وtypes
في ملفّات tsconfig.json
للاستزادة.
/// <reference lib="..." />
تسمح هذه التعليمة لملفٍّ بشمل ملفّ lib
مضمَّن (built-in lib file) موجود مسبقًا شملًا صريحًا (explicitly).
تُحال ملفّات lib
المضمّنة بنفس طريقة خيار المترجم "lib"
في ملفّ tsconfig.json
(استعمل lib="es2015"
عوضًا عن lib="lib.es2015.d.ts"
مثلًا).
تعليمات /// <reference lib="..." />
هي الطريقة المنصوح بها لكُتّاب ملفات التعريفات الذين يعتمدون على الأنواع المضمَّنة (مثل واجهات DOM البرمجيّة أو الدوال البانية في JavaScript في زمن التنفيذ مثل Symbol
أو Iterable
).
ملاحظة: كان من الواجب مسبقًا على ملفّات .d.ts
إضافة تقديم (forward) تصريحات أو تصريحات مكرّرة لهذه الأنواع.
على سبيل المثال، إضافة /// <reference lib="es2017.string" />
إلى أحد الملفات في ترجمةٍ مكافئ للترجمة باستخدام الخيار --lib es2017.string
:
/// <reference lib="es2017.string" />
"foo".padStart(4);
/// <reference no-default-lib="true"/>
تُعلِّم هذه التعليمة ملفًّا على أنّه مكتبة افتراضيّة (default library). سترى هذه التعليمة في أعلى الملفّ lib.d.ts
وما شابهه.
ترشد هذه التعليمة المترجمَ إلى ألّا يشمل المكتبة الافتراضية (lib.d.ts
) في الترجمة. وتأثير ذلك شبيه بتمرير الخيار --noLib
إلى سطر الأوامر.
لاحظ كذلك أن تمرير --skipDefaultLibCheck
سيجعل المترجمَ يتجاهل التحقق فقط من الملفّات التي تحتوي على /// <reference no-default-lib="true"/>
.
/// <amd-module />
تولَّد وحدات AMD افتراضيًا مع تجاهل الاسم. ما قد يُحدِث مشاكل عندما تُستَخدَم أدوات أخرى لمعالجة الوحدات الناتجة مثل المُجمِّعات (مثل r.js
).
تسمح تعليمة amd-module
بتمرير اسم وحدة اختياريّ إلى المترجم:
(الملفّ amdModule.ts
)
///<amd-module name="NamedModule"/>
export class C {
}
سيُنتِج هذا تعيينَ الاسم NamedModule
إلى الوحدة كجزء من استدعاء الدالة define
الخاصة بوحدات AMD:
(الملفّ amdModule.js
)
define("NamedModule", ["require", "exports"], function (require, exports) {
var C = (function () {
function C() {
}
return C;
})();
exports.C = C;
});
/// <amd-dependency />
ملاحظة: هذه التعليمة مُهملَة (deprecated). استعمل جُمل import "moduleName";
عوضًا عنها.
تُعلِم التعليمة /// <amd-dependency path="x" />
المترجمَ إلى وجود اعتمادٍ على وحدةٍ غير مكتوبة بلغة TypeScript يجب حقنُها في استدعاء require
الخاصّ بالوحدة الناتجة.
يُمكن لتعليمة amd-dependency
أن تحتوي كذلك على خاصيّة name
اختياريّة؛ ما يسمح لتمرير اسمٍ اختياريّ لاعتماديّة AMD:
/// <amd-dependency path="legacy/moduleA" name="moduleA"/>
declare var moduleA:MyType
moduleA.callStuff()
شيفرة JavaScript المولّدَة:
define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) {
moduleA.callStuff()
});