ما هو TypeScript؟

0 الأسهم
0
0
0
0

مقدمة

تايب سكريبت لغة برمجة عامة تُستخدم في بيئات تطوير متنوعة. على مر السنين منذ إصدارها، حظيت بدعم كبير من المطورين والشركات، ويتجلى ذلك في تصنيفها من قِبل GitHub كرابع أكثر لغات البرمجة استخدامًا في عام ٢٠٢٢. ومنذ ذلك الحين، ازدادت شهرة تايب سكريبت.

علاوة على ذلك، تنعكس شعبيتها في وفرة فرص العمل، مع الإعلان عن أكثر من 20 ألف وظيفة مرتبطة بـ TypeScript على LinkedIn واختيار كبار اللاعبين في الصناعة، بما في ذلك Trivago و Stripe، نقل مجموعات التكنولوجيا الخاصة بهم إلى TypeScript.

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

TypeScript مقابل JavaScript

تايب سكريبت ليس جديدًا كليًا. إنه مجموعة فرعية من جافا سكريبت تُعالج قيود جافا سكريبت نفسها. كمجموعة فرعية، يُوسّع تايب سكريبت جافا سكريبت بإضافة كتابة ثابتة.

يمكن إعلان هذا النوع الثابت بطريقتين شائعتين:

1. تعليقات النوع

يتضمن هذا تحديد المتغيرات وأنواعها فورًا عند إعلانها لأول مرة. كما يلي:

let name: string = "Hygraph

حيث أن name هو اسم المتغير و string هو نوعه.

2. أسماء النوع البديلة

تتضمن هذه الطريقة تعريف نوع بشكل منفصل باستخدام الكلمة الأساسية type واستخدامها لاحقًا لتوضيح المتغيرات.

type StringType = {
name: string;
};
let name: StringType = { name: "Hygraph" };

الآن، دعونا نلقي نظرة على بعض الميزات التي يقدمها TypeScript.

أهم ميزات TypeScript

الكتابة الثابتة

يشير النوع الثابت إلى عندما يتم الإعلان عن المتغيرات صراحةً بأنواع البيانات الخاصة بها (مثل عدد صحيح، سلسلة، منطقي) في وقت التجميع ويقوم النظام بإجراء فحص النوع قبل تنفيذ البرنامج.

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

let name: string = "hygraph";
name = 2000
الكتابة الاختيارية

بينما يسمح TypeScript بالإعلان الصريح عن المتغيرات، فإنه يدعم أيضًا كتابة أكواد شبيهة بـ JavaScript دون الإعلان عن الأنواع. يستنتج TypeScript النوع تلقائيًا. على سبيل المثال،

let name = "Hygraph";

في الأعلى، يستنتج TypeScript أن اسم النوع عبارة عن سلسلة من خلال قيمة تهيئة المتغير، على سبيل المثال، "Hygraph".

Generics لـ TypeScript

من خلال تحديد معلمات الأنواع والوظائف، تقوم العناصر العامة في TypeScript بإنشاء مكونات ووظائف قابلة لإعادة الاستخدام يمكنها العمل مع أنواع مختلفة دون المساس بسلامة النوع:

// Generic function to return the length of an array
function getArrayLength<T>(array: T[]): number {
return array.length;
}
// Using the generic function with different types of arrays
const stringArray: string[] = ["apple", "banana", "orange"];
const numberArray: number[] = [1, 2, 3, 4, 5];
console.log(getArrayLength(stringArray)); // Output: 3
console.log(getArrayLength(numberArray)); // Output: 5

تُعد العناصر العامة مفيدة بشكل عام في تحديد أنواع البيانات المخصصة التي تحتاج إلى العمل مع أنواع البيانات مثل الأشجار والرسوم البيانية والطوابير.

نظام النوع المتقدم

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

دعونا نفكر في بعض الأنواع المتقدمة الأكثر استخدامًا.

1. أنواع الاتحاد

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

تُمثَّل أنواع الاتحاد بالرمز |، الذي يفصل أنواع البيانات. على سبيل المثال:

let age = number | string;
age = 10;
age = "ten";

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

2. أنواع التقاطعات

تتيح عمليات التقاطع إنشاء نوع جديد بدمج عدة أنواع موجودة في نوع جديد. يتمتع هذا النوع الجديد بخصائص ووظائف الأنواع المدمجة.

يتم إنشاء التقاطعات باستخدام الرمز & بين الأنواع المراد دمجها. على سبيل المثال:

interface User {
id: number;
username: string;
email: string;
}
interface Admin {
isAdmin: boolean;
}
// A new type using intersection type
type UserAndAdmin = User & Admin;

هنا، يجمع نوع المستخدم والإدارة بين الميزات من واجهة المستخدم والإدارة لإنتاج نوع يتطلب كافة الميزات من كليهما.

3. الأنواع الشرطية

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

دعونا نفكر في مثال أساسي:

// A conditional type to determine if a type is an array
type IsArray<T> = T extends any[] ? true : false;
// Test the conditional type with different types
type Result1 = IsArray<number>; // false
type Result2 = IsArray<string[]>; // true
type Result3 = IsArray<boolean | []>; // true

تُعرَّف الأنواع الشرطية باستخدام المُعامل الثلاثي (? 🙂) بين قوسين (<>)، والمعروف باسم "معامل النوع العام" - سنتحدث عنه بمزيد من التفصيل لاحقًا في هذه المقالة. كما تستخدم الكلمة المفتاحية extends، التي تتحقق مما إذا كان النوع يُلبي شرطًا مُعينًا، وتُنتج نوعًا آخر بناءً على نتيجة هذا الشرط.

4. أنواع التعيينات

تتيح لك الأنواع المُعيَّنة في TypeScript إنشاء أنواع جديدة بتحويل خصائص الأنواع الموجودة. ويتم ذلك بتكرار خصائص نوع المصدر وتطبيق تحويل على كل خاصية لإنتاج نوع جديد. على سبيل المثال:

// type representing a user
type User = {
id: number;
username: string;
email: string;
};
// Mapped type to make all properties optional
type OptionalUser = { [P in keyof User]?: User[P] };
// New type using the mapped type
const optionalUser: OptionalUser = { id: 1 };
// Property 'email' is now optional
optionalUser.username = "john_doe";
// Property 'id' is still required
// optionalUser.email = "[email protected]"; // Error: Property 'email' is missing

يتم تعريف الأنواع المرسومة باستخدام الصيغة {[P in keyof Type]: NewType }، حيث Type هو نوع المصدر، وP هو مفتاح الخاصية، وNewType هو النوع المُحوَّل. يتكرر P عبر مفاتيح الخصائص ويُحدِّد التحويل.

5. اكتب اللقب

تتيح لك أسماء الأنواع البديلة إنشاء أسماء مخصصة (أسماء بديلة) لأنواع TypeScript الحالية، بما في ذلك الأنواع البدائية، وأنواع الاتحاد، وأنواع التقاطع، وحتى الأنواع الأكثر تعقيدًا مثل حروف الكائنات وأنواع الدوال. يُعرَّف اسم النوع البديل باستخدام الكلمة المفتاحية type متبوعةً بالاسم الجديد، كما هو موضح أدناه:

// type alias for a union type
type Result = "success" | "error";
// type alias for an object literal
type Point = { x: number; y: number };
// type alias for a function type
type Greeting = (name: string) => string;
// Using the type aliases
const status: Result = "success";
const origin: Point = { x: 0, y: 0 };
const greet: Greeting = (name) => Hello, ${name}!;

يُظهر الكود أعلاه الاستخدامات المختلفة لأسماء النوع البديلة لأنواع مختلفة في TypeScript واستخدامها بعد الإعلان.

TypeScript في البرمجة الكائنية التوجه (OOP)

OOP هو نموذج يعتمد على مفهوم "الكائنات" التي تتفاعل لإنشاء كود قابل للصيانة وإعادة الاستخدام.

1. فئات TypeScript

الفئات هي أنماط أو تصاميم لإنشاء الكائنات، أي أنها تحدد البيانات (الخصائص) والطرق (الوظائف).

فيما يلي مثال لكيفية تنفيذ فئة في TypeScript:

class Organization {
private name: string;
private yearFounded: number;
constructor(name: string, yearFounded: number) {
this.name = name;
this.yearFounded = yearFounded;
}
public getDetails(): string {
return `${this.name} was founded in ${this.yearFounded}.`;
}
}
let organization = new Organization("Hygraph", 2015);
console.log(organization.name); // Error: Property 'name' is private and only accessible within class 'Organization'.
console.log(organization.getDetails()); // Output: Hygraph was founded in 2015

في الكود أعلاه، أنشأنا فئة "Organization" بخصائص خاصة باسم yearFounded، ولا يمكن الوصول إليها وتعديلها إلا داخل فئة "Organization". لاحظ كيفية كتابة الخصائص والطرق.

2. واجهة TypeScript

تصف الواجهات شكل الكائنات من خلال سرد الخصائص والطرق التي يجب أن تمتلكها، دون تقديم تفاصيل التنفيذ:

// Interface representing form data
interface FormData {
firstName: string;
lastName: string;
email: string;
age: number;
}
// Usage
let formData: FormData = {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
age: 30
};

في المثال أعلاه، قمنا بتعريف واجهة FormData التي تمثل بنية بيانات النموذج.

بعد ذلك، قمنا بإنشاء كائن formData مع خصائص مرتبطة بتعريف الواجهة.

أرقام TypeScript

أنواع العد، التي يتم تمثيلها بواسطة enum في TypeScript، هي مجموعة من الثوابت المسماة والمحاطة بأقواس متعرجة {}، حيث يكون لكل ثابت قيمة رقمية أو سلسلة مرتبطة به.

قد تبدو قائمة TypeScript النموذجية على النحو التالي:

// enum for days of the week
enum DayOfWeek {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
enum HTTPStatusCodes { 
OK = 200, 
BadRequest = 400, 
NotFound = 404,
}

يشرح كتلة التعليمات البرمجية أعلاه على الفور ما يحدث ويوضح الفائدة الدلالية لإضافة المعنى إلى استخدام عدادات TypeScript.

TypeScript و ES6

يدعم TypeScript العديد من ميزات ECMAScript 6 (ES6)، والمعروف أيضًا باسم ECMAScript 2015. تتضمن بعض هذه الميزات ما يلي:

١) دوال الأسهم: بخلاف تعبيرات الدوال التقليدية، توفر دوال الأسهم بنية نحوية بسيطة لتعريف الدوال. فهي توفر إرجاعًا ضمنيًا للتعبيرات أحادية السطر، وتسلسلًا تلقائيًا، ويمكن أن تكون مفيدة لدوال الاستدعاء أو معالجات الأحداث.

// Arrow function
const add = (x, y) => x + y;
// Traditional function expression
const add = function(x, y) {
return x + y;
};

٢) أبجدية القالب: يتيح لك هذا تضمين تعبيرات وسلاسل نصية متعددة الأسطر مباشرةً في الكود بين قوسين ("). يُسهّل هذا إنشاء سلاسل نصية ديناميكية، بما في ذلك استيفاء المتغيرات والتعبيرات.

const name: string = "John";
const greeting: string = `Hello, ${name}!`;

هناك المزيد من ميزات ES6 التي لا تغطيها هذه المقالة. لمزيد من المعلومات، راجع Ecma International.

مزايا TypeScript مقارنة بـ JavaScript

منذ إصدار TypeScript منذ أكثر من عقد من الزمان، كان هناك نقاش مستمر حول مزاياه مقارنةً بـ JavaScript.

وفي هذا القسم، سوف نتناول بعض هذه الفوائد.

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

متى تستخدم TypeScript

من خلال التنازلات التي ناقشناها أعلاه، يمكنك استنتاج أن TypeScript قد لا يكون مناسبًا لجميع المشاريع. قد يكون هذا صحيحًا، ولكن لماذا نترك هذا القرار لك؟ دعنا نساعدك في اتخاذ قرار أفضل.

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

متى لا تستخدم TypeScript

للأسف، على الرغم من فوائده، قد لا يكون TypeScript مناسبًا لجميع حالات الاستخدام. مثل:

  • مشاريع بسيطة: بالنسبة للمشاريع الصغيرة ذات التعقيد الأدنى، قد لا تفوق فوائد الكتابة الثابتة والأدوات المتقدمة التكوين ومنحنى التعلم المرتبط بـ TypeScript.
  • قواعد البيانات القديمة: قد يكون تحويل قواعد بيانات JavaScript الكبيرة والموجودة إلى TypeScript أمرًا شاقًا. في هذه الحالات، قد لا يُبرر الجهد المبذول للانتقال إلى TypeScript الفوائد المرجوة، خاصةً إذا كان المشروع يقترب من نهاية عمره الافتراضي أو لا يخضع إلا لصيانة بسيطة.
اترك تعليقاً

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


قد يعجبك أيضاً