مقدمة إلى لغة البرمجة تايب سكريبت (TypeScript)

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

شهرة TypeScript ومعدل استخدامها في تزايد من عام إلى عام، ولعل هذا الوقت مناسب جدا لكي نكتشف معا ماهية هذه اللغة، أهدافها وعلاقتها بجافا سكريبت.

ما هي TypeScript ؟

TypeScript هي لغة برمجة صممتها شركة مايكروسوفت عام 2012 بغرض وهدف تحسين ورفع انتاجية مطوري الويب (جافا سكريبت). هذه اللغة تعتبر بمثابة توسعة للغة البرمجة جافا سكريبت بحيث توفر عددا من المزايا التي ليست مدعومة بعد بشكل رسمي من طرف جافا سكريبت أو أن دعمها محدود من طرف المتصفحات وكذلك Node.js.

ما يجب فهمه ومعرفته بشكل جيد هو أن نطاق استخدام TypeScript ينحصر فقط على مرحلة التطوير أو Development Stage، ولن تجد أثرا لهذه اللغة في بيئة الإنتاج. كل الشفرات البرمجية التي يتم كتابتها بلغة البرمجة TypeScript يتم تحويلها أو ترجمتها إلى كود جافا سكريبت قبل إعطائها للمتصفح أو Node.js أو أي بيئة أخرى مشغلة وداعمة لجافا سكريبت.

عملية الترجمة هذه تعرف باسم Transpiling وقد سبق لنا شرحها بشيء من التفصيل في مقال سابق على هذه المدونة.

الجدير بالذكر أيضا أن كل كود تايب سكريبت هو أيضا كود جافا سكريبت صالح، الفرق أن تايب سكريبت كما قلنا يضيف مزايا وإمكانيات جديدة مثل دعم الأنواع أو Type checking.

تثبيت وإعداد مترجم TypeScript

يتم تثبيت تايب سكريبت عن طريق مدير الحزم NPM كما يلي:

npm install -g typescript

البارامتر -g يعني بأننا قمنا بتثبيت الحزمة بشكل عام في جهازنا ومن الممكن استخدامها والوصول إليها من أي مشروع أو مجلد وليس المشروع الحالي فقط.

سنقوم باختبار تايب سكريبت عن طريق الكود أسفله، والذي كما تلاحظون هو مجرد كود جافا سكريبت اعتيادي، ولكنه موجود في ملف امتداده .ts وليس .js.

greeter.ts
function greeter(person) {
  return 'Hello, ' + person;
}

let user = 'Jane User';

document.body.textContent = greeter(user);

عملية الترجمة

لكي نقوم باستخدام هذا الكود في صفحة الويب يجب أولا ترجمته وتحويله إلى كود وملف جافا سكريبت. الطريقة هي كالتالي:

tsc greeter.ts

بعد الترجمة، سيتم توليد ملف greeter.js جديد في نفس المجلد الذي يوجد فيه greeter.ts.

greeter.js
function greeter(person) {
  return 'Hello, ' + person;
}
let user = 'Jane User';
document.body.textContent = greeter(user);

حصلنا على نفس الكود ولكن بصيفة .js، فأصبح بإمكاننا الآن إضافة هذا الملف واستدعاؤه من صفحتنا كما نفعل دائما عند التعامل مع ملفات جافا سكريبت.

أهم مزايا تايب سكريبت

في المثال السابق لم نستفد من أي من مميزات لغة البرمجة TypeScript، فالكود الذي حصلنا من بعد الترجمة بإمكاننا كتابته بسهولة بلغة جافا سكريبت مباشرة. ولكن أهمية TS تأتي من المميزات الكثيرة التي توفرها للمطورين والتي سنكتشفها تباعا (أهمها) في هذه الفقرة.

1. دعم الأنواع

تنقسم لغات البرمجة عموما إلى صنفين اثنين:

  • لغات تتحقق من أنواع المتغيرات خلال مرحلة الترجمة أو Compilation، ولذلك يسمى دعمها للأنواع بالدعم الستاتيكي أو الصريح (Static Type Checking). من هذه اللغات نجد جافا، ++C و Go. عندما تصادف هذه اللغات خطأ متعلق بنوع المتغير في الكود فإن الترجمة تفشل ولا تتم بنجاح.

  • وصنف آخر من اللغات يقوم بالتحقق من أنواع المتغيرات بشكل ديناميكي (Dynamic Type Checking) أثناء تشغيل البرنامج، ومن هذا الصنف نجد جافا سكريبت، بايثون و PHP.

مشكلة Dynamic type Checking أنه يؤدي في كثير من الحالات إلى برامج يصعب التأكد من اشتغالها بشكل طبيعي في وقت التشغيل (Runtime)، لهذا نجد أن نسبة كبيرة من أكثر الأخطاء التي تظهر في برامج جافا سكريبت هي أخطاء متعلقة بالأنواع!

سنعيد كتابة المثال السابق، ولكن هذه المرة سنستعين بخاصية Type checking:

greeter.ts
function greeter(person: string) {
  return 'Hello, ' + person;
}

let user = [0, 1, 2];

document.body.textContent = greeter(user);

أصبحنا نتأكد من أن البارامتر هو فعل نص أو String وإلا فإن عملية Compilation لن تتم بنجاح. فلو جربنا مثلا تمرير عدد أو مصفوفة للدالة greeter() فإن خطأ من هذا النوع سيظهر لنا وتتوقف عملية الترجمة.

error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

الأنواع المدعومة من طرف TypeScript

بالإضافة لنوع String الذي رأيناه أعلاه، تدعم لغة تايب سكريبت عددا من الأنواع الأخرى ونذكر منها أهمها:

Boolean

يستخدم هذا النوع للتأكد من أن المتغير هو فعلا Boolean ويقبل إحدى القيمتين true أو false.

let myBool: boolean = false;
Number

جميع الأعداد الصحيحة (Integers) والعشرية (Decimal) يعتبرها TypeScript من نوع Number، ويضيف إليها كذلك الأعداد من أنظمة Octal ،Hexadecimal و Binary. هذين الأخيرين مدعومين كذلك في جافا سكريبت في الإصدار ES6.

let intNumber: number = 6;
let decNumber: number = 6.5;
let hexNumber: number = 0xf00d;
let binaryNumber: number = 0b1010;
let octalNumber: number = 0o744;
Array

يدعم كذلك تايب سكريبت نوع المصفوفات، ويمكن التصريح بهذا النوع من المتغيرات بطريقتين مختلفتين:

الطريقة الأولى
let list: number[] = [1, 2, 3];

نلاحظ أننا استعملنا الكلمة number وأمامها معقوفتين [] لكي نخبر تايب سكريبت بأننا أولا نريد مصفوفة وثانيا نريد من هذه المصفوفة أن تحتوي على أعداد فقط.

الطريقة الثانية
let list: Array<number> = [1, 2, 3];

إذا أردنا مصفوفة عشوائية، بأنواع مختلطة نستعمل النوع any:

let list: any[] = [1, 'hello', true];
Any

هذا النوع فريد من نوعه مقارنة بالأنواع الأخرى. عن طريقه نرسل رسالة لمترجم تايب سكريبت بأننا غير متأكدين من نوع أو طبيعة المتغير، وأن الأخير قد يكون من أي نوع كان بحسب القيمة المسندة إليه.

يمكن النظر إلى any على أنه الأقرب إلى آلية Dynamic Typing التي تنهجها لغة البرمجة جافا سكريبت نفسها.

let notSure: any = 5;
notSure = 'hello world'; // Ok
notSure = false; // Ok

بالإضافة إلى ما ذكرناه، هناك مجموعة من الأنواع الأخرى:

  • Tuple
  • Enum
  • Void
  • Null and Undefined
  • Never
  • Object

تفاصيل وشرح لجميع الأنواع تجدونها على في هذا الرابط.

2. الدوال في تايب سكريبت

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

function greeter(name: string): string {
  return 'Hello, ' + name;
}

وإذا كانت الدالة لا ترجع أي قيمة فإننا نستعمل النوع void كما هو معمول به في العديد من لغات البرمجة المعروفة (PHP كمثال).

function doSomething(name: string): void {
  // do something
}

هناك كذلك دعم لميزة البارامتر الإختياري:

function greeter(name: string, email?: string): string {
  // do something
}

هذه الميزة موجودة اليوم في إصدار ES2015 من جافا سكريبت، ولكن بتركيب مختلف:

function greeter(name, email = ''): string {
  // do something
}

3. الواجهات (Interfaces)

تتيح لنا الواجهات تعيين الخصائص والوظائف الواجب توفرها في كائن (Object) أو صنف (Class) محدد.

نقوم بالتصريح بالواجهة في TypeScript بهذه الطريقة:

interface Person {
  firstName: string;
  lastName: string;
}

ويمكننا استخدامها تماما مثلما نستعمل الأنواع الأساسية المدعومة من لغة البرمجة Typescript.

function greeter(person: Person) {
  return 'Hello, ' + person.firstName + ' ' + person.lastName;
}

يمكن للكائن person هنا أن يحتوي على خاصيات إضافية ولكن من الضروري أن يتوفر على الأقل على الخاصيتين firstName و lastName المصرح بهما في واجهة Person.

يمكن كذلك للأصناف (Classes) أن تستعين بالواجهات للتأكد من أن الصنف يحترم البنية الموضوعة في الواجهة. إذا كانت لديك خلفية في لغات مثل سي شارب، جافا أو حتى PHP فبالتأكيد ستعرف عن ماذا نتحدث.

interface Person {
  firstName: string;
  lastName: string;
  getFullName(): string;
}
class Student implements Person {
  constructor(public firstName: string, public lastName: string) {}

  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

var student = new Student('Aissa', 'BOUGUERN');

console.log(student.getFullName()); // Aissa BOUGUERN

لاحظوا أننا استعملنا الكلمة implements لنطلب من الصنف Student اتباع بنية الواجهة Person.

4. الأصناف (Classes)

تعتبر الأصناف أو الكلاسات (شاهد المثال أعلاه) جزءًا أساسيا في البرمجة الشيئية أو Object Oriented Programming. لهذا كانت هذه الميزة من أوائل المزايا التي جاءت بها لغة تايب سكريبت بهدف سد الثغرة أو النقص الموجود في جافا سكريبت والذي كان يشتكي منه عدد كبير من مطوري الويب.

صحيح أن لغة البرمجة جافا سكريبت تدعم هذه الميزة في إصدار ES2015، ولكن ما يزال هناك مزايا عديدة موجودة حصريا في TypeScript وتتناغم بشكل جيد مع الأصناف، مثل الواجهات التي تحدثنا عنها قبل لحظات وكذلك المزخرفات أو Decorators التي ستكون بالتأكيد تعاملت معها كثيرا إذا كانت لك تجربة مع. إطار العمل أنجولار.

5. الوحدات (Modules)

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

هذه الميزة كما هو معروف تمكننا من التصريح بجمع مختلف وحدة أو وظائف معينة في ملف خاص بها، ومن ثم استيرادها واستخدامها عن الحاجة.

في الختام

جافا سكريبت لغه برمجة لديها خصوصياتها التي تجعلها مختلفة عن غيرها من اللغات، ودور TypeScript هو عصرنة أو تحديث هذه اللغة وجعلها شبيهة بلغات البرمجة الأخرى التي تتبع نمط OOP. هذا يجعلها كذلك في متناول مطوري النظم الخلفية الذي يتوجسون ـ أغلبهم ـ من جافا سكريبت.

تلعب لغة البرمجة TypeScript كذلك دورا ممتازا في تنفيذ كثير من مقترحات EcmaScript ووضعها رهن إشارة مطوري الويب بشكل مبكر قبل أن يتم تبنيها ودعمها رسميا في JavaScript. هذا ماحدث مع الأصناف والوحدات طيلة أعوام، ويحدث اليوم مع مزايا أخرى أولها التنويع أو Typing وليس آخرها المزخرفات (Decorators) والواجهات (Interfaces).