TypeScript: متى يكون الخيار الأمثل لمشروعك؟

دقائق القراءة: 9

مقدمة: رحلة تحويل قاعدة كود برمجية ضخمة

في أحد المشاريع السابقة، اضطررنا إلى تحويل قاعدة كود برمجية هائلة (تجاوزت 18,000 سطر من الكود) من JavaScript إلى TypeScript. كانت تلك التجربة فرصة رائعة للتعمق في فهم نقاط القوة والضعف لكلتا التقنيتين، وتحديد السيناريوهات التي يكون فيها استخدام إحداهما أكثر منطقية من الأخرى.

متى يكون استخدام TypeScript منطقياً؟

عندما يكون لديك قاعدة كود برمجية ضخمة

عندما تكون قاعدة الكود البرمجية لديك ضخمة، ويعمل على المشروع أكثر من مطور واحد، يمكن لنظام الأنواع (type system) أن يساعدك في تجنب الكثير من الأخطاء الشائعة. هذا ينطبق بشكل خاص على تطبيقات الصفحة الواحدة (single-page applications). في أي وقت يمكن لمطور واحد أن يُحدث تغييرات قد تكسر الكود، فمن الجيد عموماً وجود نوع من آلية الأمان.

يكشف محول TypeScript البرمجي (transpiler) عن الأخطاء الأكثر وضوحاً، على الرغم من أنه لن يلغي الحاجة إلى تصحيح الأخطاء (debugging) بطريقة سحرية. إذا لم تكن قاعدة الكود البرمجية لديك كبيرة جداً، فربما لا يكون من المنطقي زيادتها بإضافة تعريفات الأنواع (type annotations). لقد قمت بتحويل أكثر من 180 ملفاً من JavaScript إلى TypeScript، وفي معظم الحالات أضاف ذلك ما يقرب من 30% إلى الحجم الكلي للكود.

عندما يكون مطورو فريقك معتادين على اللغات ذات الأنواع الثابتة

إذا كنت أنت أو غالبية أعضاء الفريق قادمين من لغة ذات أنواع قوية (strongly typed language) مثل C# أو Java، ولا ترغبون في الانغماس كلياً في JavaScript، فإن TypeScript يعد بديلاً جيداً. على الرغم من أنني أوصي بتعلم JavaScript بشكل شامل، إلا أنه لا يوجد ما يمنعك من استخدام TypeScript دون معرفة JavaScript. في الواقع، تم إنشاء TypeScript بواسطة نفس الشخص الذي أنشأ C#، لذا فإن تركيبهما النحوي (syntax) متشابه.

في شركتنا، كان لدينا فريق من مطوري C# يقومون ببرمجة تطبيق سطح مكتب متطور باستخدام C# و WPF (وهي أساساً أداة لتطوير الواجهة الأمامية لعالم سطح المكتب). طُلب منهم بعد ذلك الانضمام إلى مشروع ويب كمطورين شاملين (full stack developers). وهكذا، في وقت قصير، تمكنوا من تعلم TypeScript للواجهة الأمامية، ثم استغلوا معرفتهم بـ C# للواجهة الخلفية.

عندما يمكن أن يحل TypeScript محل Babel

اعتادت شركة Microsoft القديمة على أخذ أدوات قياسية – مثل Java – وإضافة ميزات احتكارية غير قياسية إليها – مما أدى في هذه الحالة إلى J++. ثم حاولوا إجبار المطورين على الاختيار بين الاثنين. TypeScript يتبع نفس النهج تماماً – هذه المرة لـ JavaScript. بالمناسبة، هذه ليست أول نسخة مشتقة (fork) من JavaScript من Microsoft. ففي عام 1996، قاموا باشتقاق JavaScript لإنشاء JScript.

على الرغم من أنه استخدام أقل شيوعاً، إلا أنه من الممكن تقنياً تحويل كود ES6 إلى ES5 باستخدام محول TypeScript البرمجي. هذا ممكن لأن ES6 هو في الأساس مجموعة فرعية من TypeScript، ومحول TypeScript البرمجي يولد كود ES5. يولد محول TypeScript البرمجي كود JavaScript (EcmaScript 5) قابلاً للقراءة بشكل جيد كمخرجات. كان هذا أحد الأسباب التي جعلت فريق Angular 2 يختار TypeScript بدلاً من لغة Dart الخاصة بـ Google.

بالإضافة إلى ذلك، يحتوي TypeScript على بعض الميزات الرائعة غير الموجودة في ES6، مثل التعدادات (enums) والقدرة على تهيئة متغيرات الأعضاء في دالة البناء (constructor). أنا لست من كبار المعجبين بالوراثة (inheritance)، لكنني أجد أنه من المفيد وجود الكلمات المفتاحية public و private و protected و abstract في الفئات (classes). TypeScript يمتلكها بينما ES6 لا يمتلكها. اعتقد مطورو C# لدينا أنه أمر مذهل للغاية أن يتمكنوا من كتابة دالة لامدا (lambda function) كجسم لدالة (method) – مما أزال الصعوبات المرتبطة بالكلمة المفتاحية this.

عندما توصي به مكتبة أو إطار عمل

إذا كنت تستخدم Angular 2 أو أي مكتبة أخرى توصي بـ TypeScript، فامضِ قدماً. لكن اعلم أنه على الرغم من أن TypeScript يمكنه استخدام جميع مكتبات JavaScript فوراً، إلا أنك إذا أردت الحصول على أخطاء نحوية جيدة، فستحتاج إلى إضافة تعريفات الأنواع (type definitions) لتلك المكتبات خارجياً. لحسن الحظ، قام فريق DefinitelyTyped ببناء مستودع (repo) مدفوع بالمجتمع مع أدوات للقيام بذلك. لكن هذه لا تزال خطوة إضافية عند إعداد مشروعك.

عندما تحتاج حقاً إلى السرعة

قد يكون هذا مفاجئاً لك، ولكن كود TypeScript يمكن أن يؤدي في بعض الحالات أداءً أفضل من JavaScript. دعني أوضح لك. في كود JavaScript الخاص بنا، كان لدينا الكثير من فحوصات الأنواع (type checks). كان تطبيقاً طبياً تقنياً (MedTech app)، لذا فإن خطأ صغيراً يمكن أن يكون قاتلاً حرفياً إذا لم يتم التعامل معه بشكل صحيح. لذلك، كان الكثير من الدوال تحتوي على عبارات مثل:

 if ( typeof name !== ‘string) throw ‘Name should be string’

باستخدام TypeScript، تمكنا من إلغاء الكثير من فحوصات الأنواع هذه تماماً. وقد ظهر تأثير ذلك بشكل خاص في أجزاء الكود التي كانت تعاني سابقاً من اختناق في الأداء (performance bottleneck)، لأننا تمكنا من تخطي الكثير من فحوصات الأنواع غير الضرورية في وقت التشغيل (runtime type checking).

متى يكون من الأفضل الاستغناء عن TypeScript؟

عندما لا تستطيع تحمل “ضريبة” التحويل البرمجي الإضافية

لا توجد خطط لدعم TypeScript أصلاً في المتصفحات. قامت Chrome ببعض التجارب، لكنها ألغت الدعم لاحقاً. أظن أن هذا له علاقة بالعبء الزائد غير الضروري في وقت التشغيل. هذا يعني أنك ستحتاج دائماً إلى تحويل كود TypeScript البرمجي الخاص بك قبل تشغيله في المتصفح. بالنسبة لـ ES6 القياسي، القصة مختلفة تماماً. عندما يتم دعم ES6 من قبل معظم المتصفحات، سيصبح التحويل الحالي من ES6 إلى ES5 غير ضروري. ES6 هو أكبر تغيير في لغة JavaScript، وأعتقد أن معظم المبرمجين سيكتفون به.

بدون التحويل البرمجي، يمكنك ببساطة تعديل الملف وتحديث متصفحك. هذا كل شيء. لا يلزم وجود مراقبة (watching)، أو تحويل برمجي عند الطلب (transpiling on demand)، أو نظام بناء (build system). إذا اخترت TypeScript، فسينتهي بك الأمر إلى القيام ببعض الأعمال الإضافية لتحديد الأنواع لمكتبات وأطر عمل JavaScript الخاصة بك (باستخدام DefinitelyTyped أو كتابة تعريفات الأنواع الخاصة بك). هذا شيء لن تحتاج إلى القيام به لمشاريع JavaScript البحتة.

عندما ترغب في تجنب حالات تصحيح الأخطاء الغريبة

خرائط المصدر (Sourcemaps) تجعل تصحيح أخطاء TypeScript أسهل، لكن الوضع الحالي ليس مثالياً. هناك حالات حافة مزعجة ومربكة حقاً. أيضاً، هناك بعض المشاكل في تصحيح أخطاء الكلمة المفتاحية this والخصائص المرتبطة بها (تلميح: _this يعمل في معظم الحالات). هذا لأن Sourcemaps لا تدعم المتغيرات بشكل جيد حالياً – على الرغم من أن هذا قد يتغير في المستقبل.

عندما ترغب في تجنب العقوبات المحتملة على الأداء

في مشروعنا، كان لدينا أكثر من 9,000 سطر من كود ES5 JavaScript القديم الجيد الذي قدم قوة حصانية خالصة إلى لوحة WebGL 3D. أبقيناها على هذا النحو. محول TypeScript البرمجي (تماماً مثل Babel) يحتوي على ميزات تتطلب توليد كود إضافي (الوراثة inheritance، التعدادات enum، الأنواع العامة generics، async/await، وما إلى ذلك). بغض النظر عن مدى جودة محولك البرمجي، لا يمكنه تجاوز تحسينات المبرمج الجيد.

لذلك قررنا إبقائه في ES5 العادي لسهولة تصحيح الأخطاء والنشر (لا يوجد تحويل برمجي على الإطلاق). ومع ذلك، فإن عقوبة الأداء ربما تكون ضئيلة مقارنة بفوائد نظام الأنواع والتركيب النحوي الأكثر حداثة لمعظم المشاريع. ولكن هناك حالات تكون فيها المللي ثانية وحتى الميكرو ثانية مهمة، وفي تلك الحالات لا يوصى بالتحويل البرمجي من أي نوع (حتى مع Babel، CoffeeScript، Dart، وما إلى ذلك). لاحظ أن TypeScript لا يضيف أي كود إضافي لفحص الأنواع في وقت التشغيل. تحدث جميع فحوصات الأنواع في وقت التحويل البرمجي وتتم إزالة تعريفات الأنواع من كود JavaScript الذي تم إنشاؤه.

عندما ترغب في تعظيم مرونة فريقك

إعداد شيء ما في JavaScript أسرع. يؤدي عدم وجود نظام للأنواع إلى المرونة وسهولة تغيير الأشياء. كما أنه يجعل كسر الأشياء أسهل، لذا تأكد من أنك تعرف ما تفعله. JavaScript أكثر مرونة. تذكر أن أحد الاستخدامات الرئيسية لنظام الأنواع هو جعل كسر الأشياء صعباً. إذا كان TypeScript هو Windows، فإن JavaScript هو Linux. في عالم JavaScript، لا تحصل على “عجلات التدريب” لنظام الأنواع، ويفترض الكمبيوتر أنك تعرف ما تفعله، لكنه يسمح لك بالقيادة بشكل أسرع بكثير والمناورة بسهولة أكبر. هذا مهم بشكل خاص إذا كنت لا تزال في مرحلة النماذج الأولية (prototyping phase). إذا كان الأمر كذلك، فلا تضيع وقتك مع TypeScript. JavaScript أكثر مرونة بكثير. تذكر أن TypeScript هو مجموعة شاملة (superset) من JavaScript. هذا يعني أنه يمكنك بسهولة تحويل JavaScript إلى TypeScript لاحقاً إذا احتجت إلى ذلك.

تفضيلاتي الشخصية: JavaScript مقابل TypeScript

لا توجد لغة واحدة هي الأفضل بشكل عام. ولكن لكل مشروع فردي، توجد على الأرجح لغة ومكتبة وإطار عمل وقاعدة بيانات ونظام تشغيل واحد هو الأفضل بشكل موضوعي… لقد فهمت الفكرة. بالنسبة لمشروعنا، كان من المنطقي استخدام TypeScript. لقد حاولت إعادة هيكلة بعض مشاريعي الشخصية إلى TypeScript لكن الأمر لم يكن يستحق الجهد.

أنا شخصياً أحب 5 أشياء في TypeScript:

  1. التوافق الكامل مع ES6: من الرائع رؤية Microsoft تلعب بنزاهة مع المتصفحات الأخرى. يمكن أن يستفيد نظامنا البيئي من منافس قوي لـ Google و Mozilla و Apple. Microsoft تبذل جهداً كبيراً فيه – مثل كتابة Visual Studio Code من الصفر باستخدام TypeScript على Google Chrome، من بين جميع المنصات.
  2. نظام الأنواع اختياري: قادماً من خلفية C و Java، وجدت أن عدم وجود نظام للأنواع في JavaScript محرر. لكنني كرهت إضاعة الوقت عندما واجهت أخطاء غبية أثناء وقت التشغيل. يسمح لي TypeScript بتجنب العديد من الأخطاء الشائعة حتى أتمكن من تركيز وقتي على إصلاح الأخطاء الصعبة الحقيقية. إنه توازن جيد. أحبه. إنه ذوقي. أستخدم الأنواع كلما استطعت لأنها تمنحني راحة البال. ولكن هذا أنا.
  3. كود JavaScript الذي ينتجه محول TypeScript البرمجي قابل للقراءة جداً: إذا استخدمت TypeScript، لا أريد أن أقيد نفسي بميزات ES6 الخاصة به. أنا لست من محبي Sourcemaps، لذلك أقوم بمعظم تصحيح الأخطاء على كود JavaScript الذي تم إنشاؤه. إنه رائع للغاية. أستطيع أن أفهم تماماً لماذا اختار Angular 2 TypeScript بدلاً من Dart.
  4. تجربة تطوير TypeScript رائعة: VS Code ذكي جداً عند التعامل مع JavaScript (قد يجادل البعض بأنه أذكى بيئة تطوير متكاملة (IDE) لـ JS). لكن TypeScript يدفع الحدود إلى مستوى جديد تماماً. تعمل ميزات الإكمال التلقائي (autocompletion) وإعادة الهيكلة (refactoring) في VS Code بدقة أكبر بكثير، وهذا ليس لأن IDE ذكي للغاية. هذا كله بفضل TypeScript.
  5. تعريفات الأنواع (Type annotations) كتوثيق أساسي: إنها تعلن عن نوع البيانات التي تتوقعها كل دالة، ونتائجها والعديد من التلميحات الأخرى مثل readonly، public أو private. في تجربتي، عند محاولة إعادة هيكلة كود JavaScript إلى TypeScript، عادة ما ينتهي بي المطاف بكود أنظف بهيكل أجمل. في الواقع، لقد حسنت كتابة TypeScript من كيفية كتابتي لـ JavaScript العادي.

TypeScript ليس الحل لكل شيء. لا يزال بإمكانك كتابة كود فظيع فيه. كارهو TypeScript سيكرهون، إما بسبب الخوف من التغيير أو لأنهم يعرفون شخصاً يعرف شخصاً يخاف منه. الحياة تستمر و TypeScript يقدم ميزات جديدة لمجتمعه على أي حال. ولكن مثل React، TypeScript هي إحدى تلك التقنيات المؤثرة التي تدفع حدود تطوير الويب لدينا. سواء كنت تستخدم TypeScript أم لا، لا يضر تجربته لتكوين آرائك الخاصة حوله. لديه منحنى تعلم، ولكن إذا كنت تعرف JavaScript بالفعل، فسيكون سلساً.

💡 الخلاصة التقنية

TypeScript ليس مجرد إضافة لـ JavaScript، بل هو أداة قوية تعزز موثوقية الكود وقابليته للصيانة، خاصة في المشاريع الكبيرة ومع الفرق التي تفضل الأنظمة ذات الأنواع الثابتة. بينما يقدم مزايا مثل اكتشاف الأخطاء المبكر وتجربة تطوير محسّنة، فإنه يأتي أيضاً مع تكلفة إضافية للتحويل البرمجي وقد يقلل من المرونة الأولية في المراحل المبكرة من المشروع. الاختيار بينه وبين JavaScript يعتمد بشكل كبير على حجم المشروع، خبرة الفريق، ومتطلبات الأداء، مع إمكانية التحول إليه لاحقاً بفضل كونه مجموعة شاملة لـ JavaScript.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *