"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > إتقان الآلة الكاتبة: فهم قوة الامتدادات

إتقان الآلة الكاتبة: فهم قوة الامتدادات

تم النشر بتاريخ 2024-11-06
تصفح:102

Mastering TypeScript: Understanding the Power of extends

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

الميراث باستخدام يمتد

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

interface User {
  firstName: string;
  lastName: string;
  email: string;
}

interface StaffUser extends User {
  roles: string[];
  department: string;
}

const regularUser: User = {
  firstName: "John",
  lastName: "Doe",
  email: "[email protected]"
};

const staffMember: StaffUser = {
  firstName: "Jane",
  lastName: "Smith",
  email: "[email protected]",
  roles: ["Manager", "Developer"],
  department: "Engineering"
};

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

الميراث الطبقي

يتم استخدام الكلمة الأساسية الممتدة أيضًا لوراثة الفصل:

class Animal {
  constructor(public name: string) {}

  makeSound(): void {
    console.log("Some generic animal sound");
  }
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name);
  }

  makeSound(): void {
    console.log("Woof! Woof!");
  }

  fetch(): void {
    console.log(`${this.name} is fetching the ball!`);
  }
}

const myDog = new Dog("Buddy", "Golden Retriever");
myDog.makeSound(); // Output: Woof! Woof!
myDog.fetch(); // Output: Buddy is fetching the ball!

هنا، يقوم الكلب بتوسيع نطاق الحيوان، ويرث خصائصه وأساليبه، ويضيف خصائصه وأساليبه أيضًا.

اكتب القيود في الأدوية العامة

تعد الكلمة الأساسية Extends أمرًا بالغ الأهمية عند العمل مع الأدوية العامة، مما يسمح لنا بتقييد الأنواع التي يمكن استخدامها مع وظيفة أو فئة عامة.

interface Printable {
  print(): void;
}

function printObject(obj: T) {
  obj.print();
}

class Book implements Printable {
  print() {
    console.log("Printing a book.");
  }
}

class Magazine implements Printable {
  print() {
    console.log("Printing a magazine.");
  }
}

const myBook = new Book();
const myMagazine = new Magazine();

printObject(myBook);      // Output: Printing a book.
printObject(myMagazine);  // Output: Printing a magazine.
// printObject(42);       // Error, number doesn't have a 'print' method
  1. واجهة قابلة للطباعة: هنا، نحدد واجهة تسمى قابلة للطباعة. تعلن هذه الواجهة عن عقد يجب على أي فئة تنفذه الالتزام به. يحدد عقد Tha أن أي فئة تطبق Printable يجب أن توفر طريقة تسمى print والتي لا تأخذ أي وسيطات وترجع فارغة
  2. وظيفة printObject(obj: T): هذه وظيفة عامة تسمى printObject. يستغرق الأمر وسيطة واحدة تسمى obj، وهي من النوع T. ومعلمة النوع T مقيدة بالأنواع التي تعمل على توسيع (تنفيذ) الواجهة القابلة للطباعة والتي يمكن استخدامها كوسيطة لهذه الوظيفة.
  3. فئة الكتاب تنفذ قابلة للطباعة وفئة مجلة تنفذ قابلة للطباعة: هنا، نحدد فئتين، الكتاب والمجلة، وكلاهما ينفذ الواجهة القابلة للطباعة. وهذا يعني أن هذه الفئات يجب أن توفر طريقة طباعة كما هو مطلوب بموجب عقد الواجهة القابلة للطباعة.
  4. const myBook = new Book(); و const myMagazine = new Magazine();: نقوم بإنشاء مثيلات لفئات الكتب والمجلات.
  5. printObject(myBook); و printObject(myMagazine);: نسمي وظيفة printObject مع مثيلات Book and Magazine. نظرًا لأن فئتي الكتب والمجلات تنفذان الواجهة القابلة للطباعة، فإنهما يستوفيان قيد معلمة النوع T الممتدة القابلة للطباعة. داخل الدالة، يتم استدعاء طريقة الطباعة للفئة المناسبة، مما يؤدي إلى الإخراج المتوقع.
  6. // printObject(42);: إذا حاولنا استدعاء printObject بنوع لا يطبق الواجهة القابلة للطباعة، مثل الرقم 42، فسيؤدي TypeScript إلى ظهور خطأ. وذلك لأن قيد النوع غير مستوفي، حيث أن الرقم لا يحتوي على طريقة طباعة كما هو مطلوب بواسطة الواجهة القابلة للطباعة.

باختصار، يتم استخدام الكلمة الأساسية الممتدة في سياق الوظيفة printObject(obj: T) للتأكد من أن النوع T المستخدم كوسيطة يلتزم بالعقد المحدد بواسطة الواجهة القابلة للطباعة. يضمن ذلك إمكانية استخدام الأنواع التي لها طريقة طباعة فقط مع وظيفة printObject، مما يفرض سلوكًا وعقدًا محددين لاستخدام الوظيفة.

أنواع الشرط

T extends U ? X : Y
  • T هو النوع الذي يتم فحصه
  • U هو نوع الشرط الذي يتم التحقق من T مقابله.
  • X هو النوع الذي يتم تقييم النوع الشرطي إليه إذا كان T ممتدًا (قابل للتخصيص) لـ U
  • Y هو النوع الذي يتم تقييم النوع الشرطي إليه إذا لم يمتد T إلى U
type ExtractNumber = T extends number ? T : never;

type NumberOrNever = ExtractNumber; // number
type StringOrNever = ExtractNumber; // never

هنا، يأخذ النوع ExtractNumber معلمة النوع T. يتحقق النوع الشرطي مما إذا كان T يوسع نوع الرقم. إذا كان الأمر كذلك، يتحول النوع إلى T (وهو نوع الرقم). إذا لم يحدث ذلك، فسيتحول النوع إلى "أبدًا".

تمتد الكلمة الأساسية مع أنواع الاتحاد

الآن، لنفكر في التعبير A | ب | يمتد C إلى A. قد يبدو هذا غير بديهي في البداية، ولكن في TypeScript، هذا الشرط غير صحيح في الواقع. وإليكم السبب:

  1. في TypeScript، عند استخدام الامتدادات مع نوع الاتحاد على الجانب الأيسر، فهذا يعادل السؤال: "هل كل نوع ممكن في هذا الاتحاد قابل للتخصيص للنوع الموجود على اليمين؟"
  2. وبعبارة أخرى، أ | ب | يسأل C الممتد A: "هل يمكن تعيين A إلى A، وهل يمكن تعيين B إلى A، وهل يمكن تعيين C إلى A؟"
  3. بينما يمكن بالتأكيد تعيين A إلى A، فقد لا يمكن تعيين B وC إلى A (ما لم تكن أنواعًا فرعية من A)، وبالتالي فإن النتيجة الإجمالية خاطئة.
type Fruit = "apple" | "banana" | "cherry";
type CitrusFruit = "lemon" | "orange";

type IsCitrus = T extends CitrusFruit ? true : false;

type Test1 = IsCitrus; // true
type Test2 = IsCitrus; // false
type Test3 = IsCitrus; // false

في هذا المثال، IsCitrus غير صحيح لأنه ليست كل الفواكه في اتحاد الفاكهة هي CitrusFruit.

أفضل الممارسات والنصائح

  • يمتد الاستخدام للعلاقات ذات المعنى: استخدم الميراث فقط عندما تكون هناك علاقة واضحة "is-a" بين الأنواع.
  • تفضيل التكوين على الميراث: في كثير من الحالات، يمكن أن يكون التكوين (باستخدام الواجهات وتقاطعات الكتابة) أكثر مرونة من وراثة الفئة.
  • كن حذرًا مع سلاسل الميراث العميقة: الميراث العميق يمكن أن يجعل فهم التعليمات البرمجية والحفاظ عليها أكثر صعوبة.
  • الاستفادة من الأنواع الشرطية لواجهات برمجة التطبيقات المرنة: استخدم الأنواع الشرطية ذات الامتدادات لإنشاء واجهات برمجة التطبيقات التي تتكيف بناءً على أنواع الإدخال.
  • يمتد الاستخدام بشكل عام لإنشاء وظائف قابلة لإعادة الاستخدام وآمنة للنوع: يتيح لك هذا كتابة الوظائف التي تعمل مع مجموعة متنوعة من الأنواع مع الحفاظ على أمان النوع
بيان الافراج تم نشر هذه المقالة على: https://dev.to/hasanm95/mastering-typescript-understanding-the-power-of-extends-1n2o?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3