تخطي إلى المحتوى الرئيسي

أنواع الأدوات المساعدة (Utility Types) في TypeScript

أنواع الأدوات المساعدة (Utility Types) في TypeScript

مقدمة عن الأدوات المساعدة (Utility Types)

في عالم تطوير البرمجيات الحديث، أصبحت TypeScript أداة لا غنى عنها لبناء تطبيقات قوية وموثوقة وقابلة للتوسع. يكمن جوهر قوتها في نظام الأنواع الثابت (Static Type System) الذي يسمح للمطورين بالتقاط الأخطاء المحتملة في مرحلة التطوير بدلاً من مرحلة التشغيل. ومع ذلك، فإن قوة TypeScript لا تتوقف عند تعريف الأنواع الأساسية فحسب، بل تمتد لتشمل مجموعة من الأدوات المتقدمة التي تُعرف بـ “الأدوات المساعدة” أو “Utility Types”.

تُعد الأدوات المساعدة مجموعة من الأنواع المضمنة (Built-in Types) في TypeScript التي تتيح لنا إجراء عمليات تحويل على الأنواع الموجودة. بعبارة أخرى، إنها وظائف على مستوى الأنواع (Type-level Functions) تأخذ نوعًا واحدًا أو أكثر كمدخل، وتُعيد نوعًا جديدًا مُعدَّلاً كناتج. تخيل أن لديك قالبًا لبيانات معينة، وترغب في إنشاء نسخة من هذا القالب مع بعض التعديلات الطفيفة – هذا هو بالضبط ما تفعله الأدوات المساعدة، ولكن على مستوى الأنواع.

ما هي الأدوات المساعدة (Utility Types)؟

بشكل أساسي، الأدوات المساعدة هي مجموعة من الأنواع المُعدة مسبقًا في TypeScript التي تمكنك من التلاعب بالأنواع بطرق قوية ومرنة. بدلاً من تعريف أنواع جديدة تمامًا لكل سيناريو مختلف (مثل جعل جميع خصائص كائن اختياريّة، أو جعلها للقراءة فقط، أو استخلاص مجموعة فرعية من الخصائص)، توفر الأدوات المساعدة طريقة معيارية ومُحكمة لإنجاز هذه المهام. إنها تعمل كـ “محولات” (Transformers) للأنواع، مما يسمح لك ببناء أنواع معقدة وديناميكية من أنواع أبسط وأساسية.

على سبيل المثال، إذا كان لديك نوع يمثل “مستخدم”، وترغب في إنشاء نوع جديد يمثل “مستخدمًا جديدًا” حيث تكون جميع الخصائص اختيارية (لأن المستخدم قد لا يقدمها كلها عند التسجيل)، بدلاً من إعادة كتابة النوع بالكامل مع علامة الاستفهام لكل خاصية، يمكنك استخدام أداة مساعدة جاهزة مثل Partial<T> لتحقيق ذلك بسطر واحد:

interface BaseUser {
  id: string;
  name: string;
  email: string;
}

// تحويل جميع الخصائص إلى اختيارية باستخدام Partial
type OptionalUser = Partial<BaseUser>;

الأدوات المساعدة الأساسية (Basic Utility Types) والتحكم البرمجي

1. التعابير الشرطية (Conditional Expressions)

في هذا القسم الفرعي، سنتناول التعابير الشرطية ودورها في توفير الوقت والجهد أثناء كتابة الأكواد البرمجية.

التعبير الشرطي هو عبارة برمجية تسمح بتنفيذ كود معين بناءً على شرط معين. في TypeScript، يمكن استخدام التعابير الشرطية بأشكال متعددة:

  • if-else للتعبير عن تنفيذ كود معين إذا تحقق شرط معين وتنفيذ كود آخر إذا لم يتحقق الشرط.
  • if-elseif-else للتعبير عن تنفيذ كود معين إذا تحقق شرط معين، وإذا لم يتحقق الشرط الأول يتم التحقق من الشرط التالي وهكذا.
  • switch-case للتعبير عن تنفيذ كود معين بناءً على قيمة معينة.

دعونا نأخذ مثالاً لتوضيح استخدام التعابير الشرطية:

function greetUser(name: string) {
  if (name === "John") {
    console.log("مرحبا يا جون!");
  } else if (name === "Jane") {
    console.log("مرحبا يا جين!");
  } else {
    console.log(`مرحبا بك ${name}!`);
  }
}

في المثال السابق، تم استخدام التعابير الشرطية لتحديد كيفية تحية المستخدم بناءً على الاسم المدخل:

  • في حالة كان الاسم “John”، سيتم طباعة “مرحبا يا جون!” على وحدة التحكم.
  • في حالة كان الاسم “Jane”، سيتم طباعة “مرحبا يا جين!” على وحدة التحكم.
  • في حالة لم يتطابق الاسم مع الحالتين السابقتين، سيتم طباعة رسالة عامة تقول “مرحبا بك ${name}!” على وحدة التحكم، حيث يُستخدم ${name} لاستبدال قيمة المتغير بالاسم المدخل.

2. التعابير التكرارية (Iterative Expressions)

التعبيرات التكرارية هي أدوات مهمة لتنفيذ عمليات تكرارية داخل الأكواد البرمجية. في هذا القسم الفرعي، سنتناول بعض التعبيرات التكرارية المستخدمة بشكل شائع:

  • for: يستخدم للتكرار على مجموعة من العناصر وتنفيذ كود معين لكل عنصر.
  • for-in: يستخدم للتكرار على خصائص كائن وتنفيذ كود معين لكل خاصية.
  • for-of: يستخدم للتكرار على تسلسلات مثل المصفوفات والمجموعات وتنفيذ كود معين لكل عنصر.

دعونا نلقي نظرة على مثال يوضح استخدام التعبيرات التكرارية:

for (let i = 0; i < 10; i++) {
  console.log(i);
}

في المثال السابق، تم استخدام الأمر for للتكرار على المتغير ‘i’ من القيمة 0 إلى 9 وطباعة القيمة كل مرة.

3. التعابير اللامتناهية (Infinite Expressions) والتكرار عبر While

تُستخدم التعابير اللامتناهية لأداء عمليات تكرارية حتى يتم استيفاء شرط معين للتوقف. في هذا القسم الفرعي، سنتناول مثالاً على استخدام while:

let i = 0;
while (i < 10) {
  console.log(i);
  i++;
}

في المثال السابق، تم استخدام التعبير while لطباعة الأرقام من 0 إلى 9 وزيادة قيمة المتغير ‘i’ قبل الانتقال للتكرار التالي.

4. التعابير التكرارية عبر حلقة for المعيارية

let count = 0;
for (; count < 10; count++) {
  console.log(count);
}

في المثال السابق، تم استخدام التعبير التكراري for لطباعة الأرقام من 0 إلى 9 بصيغة التهيئة الخارجية.

5. التكرار عبر خصائص الكائنات بواسطة for…in

تُستخدم التعابير التكرارية لتكرار العمليات على خصائص الكائنات:

let obj = {name: "John", age: 30};
for (let key in obj) {
  console.log(obj[key as keyof typeof obj]);
}

في المثال السابق، تم استخدام التعبير التكراري for...in لطباعة الخصائص الموجودة في الكائن “obj”.

6. التكرار المباشر عبر عناصر المصفوفة بواسطة for…of

let arr = [1, 2, 3, 4, 5, 6];
for (let item of arr) {
  console.log(item);
}

في المثال السابق، تم استخدام التعبير التكراري for...of لطباعة القيم الموجودة في المصفوفة “arr”.

7. التكرار وحساب عدد مرات المعالجة

let numericArr = [1, 2, 3, 4, 5, 6];
let counter = 0;
for (let item of numericArr) {
  console.log(item);
  counter++;
}
console.log(counter);

في المثال السابق، تم استخدام التعبير التكراري for...of لطباعة القيم وزيادة قيمة العداد بعد كل تكرار.

8. التكرار على مصفوفات النصوص مع حساب العداد

let namesArr = ["John", "Mary", "Alice", "Bob"];
let indexCounter = 0;
for (let item of namesArr) {
  console.log(item);
  indexCounter++;
}
console.log(indexCounter);

في المثال السابق، تم استخدام التعبير التكراري for...of لطباعة قيم مصفوفة النصوص “namesArr” وتتبع التكرار.

القسم رقم 3: الأدوات المساعدة المتقدمة (Advanced Utility Types)

الأدوات المساعدة للتعبيرات الشرطية (Conditional Utility Types)

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

الأدوات المساعدة للتعبيرات التكرارية (Iterable Utility Types)

توفر TypeScript مجموعة من الأدوات المساعدة للتعبيرات التكرارية التي تسهل التعامل مع البيانات المتكررة والتكرار عليها بكفاءة. في هذا الجزء، سنستعرض بعض الأدوات المساعدة المهمة للتعبيرات التكرارية وكيف يمكن استخدامها لتحسين أداء الكود البرمجي وتقليل عدد الأسطر المستخدمة.

الأدوات المساعدة للتعبيرات اللامتناهية

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

استخدام الأدوات المساعدة المتقدمة في TypeScript

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

أنواع الأدوات المساعدة المدمجة (Built-in Utility Types)

في TypeScript، توفر اللغة مجموعة من الأدوات المساعدة المدمجة التي تعتبر جزءاً أساسياً منها، وتساهم بشكل فعال في تحسين جودة الكود البرمجي وتقليل الأخطاء البرمجية:

الأدوات المساعدة الأساسية

  • RegExp: تُستخدم للعمل مع التعبيرات العادية ومطابقة الأنماط.
  • String: تتعامل مع النصوص والعمليات المتعلقة بها.
  • Number: تتعامل مع العمليات الحسابية والتحويلات العددية.

الأدوات المساعدة المتقدمة للبيانات

  • Array: تتعامل مع المصفوفات والعمليات المتعلقة بها من فلترة وتجميع.
  • Object: تتعامل مع الكائنات ومفاتيحها والعمليات الهيكلية عليها.
  • RegExp: توسيعات متقدمة للتحقق من الأنماط النصية.

أنواع الأدوات المساعدة المخصصة (Custom Utility Types)

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

فوائد استخدام الأدوات المساعدة المخصصة

  • تعزيز جودة الكود:
    • إنشاء قواعد ومعايير مخصصة للكود.
    • التحقق من صحة البيانات والأعمال المنطقية.
    • توحيد الممارسات البرمجية عبر الفريق.
  • تحسين الكفاءة:
    • توفير الوقت في كتابة الأكواد المتكررة.
    • توحيد الممارسات البرمجية وتقليل الأخطاء البرمجية.
    • تخصيص الوظائف المعقدة لتحسين الأداء.
  • ضمان الأمان:
    • توفير فحوصات أمان مخصصة.
    • منع الأخطاء الناتجة عن استخدام أنواع بيانات خاطئة أو غير متوافقة.
    • ضمان التوافق والتكامل بين مكونات المشروع.

كيفية إنشاء أداة مساعدة مخصصة

  1. تحديد المشكلة والحل: حدد المشكلة التي ترغب في حلها وقدم حلاً مخصصاً.
  2. تصميم الأداة المساعدة: قم بتصميم الأداة المساعدة بطريقة واضحة ومنظمة لضمان سهولة استخدامها وفهمها.
  3. توثيق الأداة المساعدة: قم بتوثيق الأداة المساعدة بشكل جيد لمساعدة الآخرين على فهم الغرض منها وكيفية استخدامها بكفاءة.

أمثلة برمجية للأدوات المساعدة المخصصة للتحقق من البيانات

/*
* أداة مساعدة مخصصة للتحقق من صحة أنواع البيانات
*/
class DataValidationCheck {
    // دالة للتحقق من صحة الأعداد الصحيحة
    static checkInt(data: number): boolean {
        if (typeof data !== 'number') {
            return false;
        }

        if (data < 0 || isNaN(data)) {
            return false;
        }

        return true;
    }
}

// مثال على استخدام الأداة المساعدة المخصصة
const inputData = 12.5;
console.log(DataValidationCheck.checkInt(inputData));

// أداة مساعدة مخصصة أخرى للتحقق من صحة النصوص
class TextValidationCheck {
    static checkString(data: string): boolean {
        if (data === '' || data === null || data === undefined) {
            return false;
        }

        return true;
    }
}

const inputString = 'مثال على نص';
console.log(TextValidationCheck.checkString(inputString));

// أداة مساعدة مخصصة للتحقق من صحة الأعداد الصحيحة الإيجابية فقط
class PositiveIntegerCheck {
    static checkPositiveInteger(data: number): boolean {
        if (data == null || data == undefined) {
            return false;
        }

        if (data < 0) {
            return false;
        }

        return true;
    }
}

const inputInteger = -123;
console.log(PositiveIntegerCheck.checkPositiveInteger(inputInteger));

// إنشاء أداة مساعدة مخصصة لمعالجة الأخطاء
class ErrorChecker {
    static checkError(message: string): boolean {
        let errorMessage = message;
        if (errorMessage === undefined) {
            return false;
        }

        return true;
    }
}

const inputError = 'خطأ في معالجة البيانات';
console.log(ErrorChecker.checkError(inputError));

إنشاء أداة مساعدة مخصصة PositiveIntegerChecker

class PositiveIntegerChecker {
    static checkPositiveInteger(number: number): boolean {
        if (typeof number !== 'number') {
            return false;
        }

        if (number < 0) {
            return false;
        }

        return true;
    }
}

const testNumber: number = 10;
console.log(PositiveIntegerChecker.checkPositiveInteger(testNumber)); // true

استخدام الأدوات المساعدة في تطوير البرمجيات (Applying Utility Types in Software Development)

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

تحسين سلامة الكود وثباته وتقليل الأخطاء في وقت الترجمة

أحد الأهداف الأساسية لـ TypeScript هو توفير طبقة إضافية من الأمان للبرمجيات من خلال التحقق من الأنواع. باستخدام الأدوات المساعدة مثل Pick و Omit، يمكننا اشتقاق كائنات نقل البيانات (DTOs) دون إرسال أو استقبال حقول حساسة ككلمات المرور:

interface User {
  id: string;
  name: string;
  email: string;
  passwordHash: string;
  createdAt: Date;
  updatedAt: Date;
}

// إنشاء DTO لبيانات الملف الشخصي العامة باستثناء كلمة المرور
type PublicUserProfile = Omit<User, "passwordHash">;

// إنشاء نموذج لبيانات تسجيل الدخول فقط باختيار البريد وكلمة المرور
type LoginPayload = Pick<User, "email" | "passwordHash">;

أفضل الممارسات لاستخدام الأدوات المساعدة (Utility Types)

الأدوات المساعدة هي مجموعة من الأدوات البرمجية المصممة لتبسيط العمليات وتوفير الوقت والجهد، لكن استخدامها يجب أن يخضع لضوابط واضحة:

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

أفضل الممارسات للتعامل مع البيانات والأنواع والوقت والتاريخ

  • التعامل مع السلاسل: استخدم الأدوات المساعدة المخصصة لتوحيد تنسيق ومعالجة النصوص.
  • التعامل مع الأرقام: تنظيم العمليات الحسابية والتحقق من النطاقات العددية بدقة.
  • التعامل مع المصفوفات والوظائف: تنظيم العمليات المتكررة على العناصر وتجنب الآثار الجانبية.
  • التعامل مع الأخطاء: توحيد صيغ رسائل الأخطاء وتسهيل تتبعها ومعالجتها.
  • التعامل مع الوقت والتاريخ: استخدام صيغ موحدة مثل ISO 8601 لتبادل التواريخ وضمان دقة التحويلات بين المناطق الزمنية.

أمثلة تطبيقية على استخدام الأدوات المساعدة (Applied Examples of Using Utility Types)

استخدام الأدوات المساعدة في التعامل مع الأخطاء وثبات البيانات

  • استخدام نوع Partial<T> للتعامل مع القيم الاختيارية وتجنب أخطاء الحقول المفقودة.
  • استخدام نوع Readonly<T> لمنع تعديل القيم بعد تعيينها وتحسين ثبات البيانات.
  • استخدام نوع ReadonlyArray<T> لضمان عدم تعديل المصفوفات بعد إنشائها وتحسين الأداء.

استخدام الأدوات المساعدة في التعامل مع السلاسل والأعداد والأوقات

  • استخدام الطرق النصية المدمجة: toLowerCase()، toUpperCase()، repeat()، و split().
  • استخدام ReadonlyMap<K, V> لضمان ثبات الخرائط والبيانات المخزنة.
  • استخدام أدوات تحويل التواريخ من صيغة ISO إلى كائن Date والعكس عبر دوال مساعدة معيارية.
  • استخدام دوال المصفوفات القياسية: forEach()، filter()، و reduce().
  • التحقق من صحة الأعداد والقيم عبر isNaN() ودوائر التحويل للقيم الأساسية (Primitive conversion).

أمثلة عملية على التعامل مع المصفوفات والمصفوفات العددية و TypedArray

يوضح المثال التالي كيفية التعامل مع تحويل وفحص المصفوفات العادية والعددية ومصفوفات البيانات الثنائية TypedArray:

class ArrayUtilities {
    // التحقق من TypedArray
    static isTypedArray(val: unknown): boolean {
        return ArrayBuffer.isView(val) && !(val instanceof DataView);
    }

    // التحقق من المصفوفات العادية
    static isArray(val: unknown): boolean {
        return Array.isArray(val);
    }

    // تحويل مصفوفة إلى مصفوفة عددية للقراءة فقط
    static toReadonlyNumberArray(numbers: number[]): ReadonlyArray<number> {
        return Object.freeze([...numbers]);
    }
}

const rawNumbers = [10, 20, 30];
const readonlyNumbers = ArrayUtilities.toReadonlyNumberArray(rawNumbers);
console.log(ArrayUtilities.isArray(rawNumbers)); // true

استنتاج ومراجعة (Conclusion and Review)

في ختام هذا الدرس الشامل من دورة “TypeScript من الصفر إلى الاحتراف باللغة العربية” (الدرس #24)، نؤكد على أن الأدوات المساعدة (Utility Types) تمثل ركناً أساسياً في تطوير البرمجيات الاحترافية بلغة TypeScript.

أهمية الأدوات المساعدة في TypeScript

  • تسريع التطوير: توفير نماذج تحويل جاهزة تقلل الحاجة لإعادة كتابة الأكواد والأنواع من الصفر.
  • تعزيز كفاءة الكود: تقديم حلول قياسية للأمان النوعي والتحقق البرمجي.
  • تعزيز التعاون بين المطورين: توحيد بنية البيانات المشتركة وتسهيل صيانة المشاريع الكبيرة.

استعراض موجز لأقسام الدرس والخطوات القادمة

استعرضنا خلال هذا المقال:

  • الأدوات المساعدة الأساسية: والتحكم البرمجي الشرطي والتكراري في صياغة الكود.
  • الأدوات المساعدة المتقدمة: التعامل مع التعبيرات الشرطية، والتحويلات الديناميكية للأنواع.
  • الأدوات المساعدة المخصصة: كيفية بناء فئات وأنواع تحقق أمان مخصصة مثل PositiveIntegerChecker.
  • التطبيقات الواقعية في هندسة البرمجيات: استخدام Pick و Omit و Partial و Readonly لإنشاء كائنات DTOs آمنة وفعالة.

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


اكتشاف المزيد من كود التطور

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

🎓 التقدم التعليمي في هذا الدرس
هل أتممت فهم وتطبيق هذا الدرس؟ اضغط على الزر لتسجيل إنجازه وكسب 10 نقاط!
MOHAMMAD ABU KASHREEF

MOHAMMAD ABU KASHREEF

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

اترك رد