أنواع العلامات التجارية في TypeScript

عندما تقوم بنمذجة الكيانات باستخدام TypeScript، من الشائع جدًا الحصول على واجهة مثل هذه:

TypeScript

 

المشكلة

أنواع الخصائص ليس لها معنى دلالي. من حيث الأنواع، User.id، Order.id، Order.year، إلخ. هي نفسها: رقم، وكأرقام فهي قابلة للتبادل، لكن دلاليًا، ليست كذلك.

استنادًا إلى المثال السابق، يمكن أن يكون لدينا مجموعة من الدوال التي تقوم بعمليات على الكيانات. على سبيل المثال:

TypeScript

 

ستقبل هذه الدوال أي رقم في أي وسيط بغض النظر عن المعنى الدلالي للرقم. على سبيل المثال:

TypeScript

 

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

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

الحل

تقدم قواعد تمارين الكائنات حلاً لذلك: لف جميع البدائيات والسلاسل (نمط مكافحة هوس البدائيات المرتبط). القاعدة هي لف البدائيات في كائن يمثل معنى دلاليًا (يصف DDD ذلك باسم ValueObjects).

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

أنواع العلامات

يستخدم هذا النمط قابلية توسيع الأنواع لإضافة خاصية تضمن المعنى الدلالي:

TypeScript

 

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

TypeScript

 

تعميم الحل

لتجنب كتابة نوع لكل نوع مميز، يمكننا إنشاء نوع مساعد مثل:

TypeScript

 

يستخدم رمزاً فريداً كاسم خاصية العلامة لتجنب التعارض مع خصائصك ويحصل على النوع الأصلي والعلامة كمعاملات عامة.

بهذا، يمكننا إعادة هيكلة نماذجنا ودوالنا كما يلي:

TypeScript

 

الآن، في هذا المثال، ستظهر IDE خطأً حيث أن id هو UserId وdeleteOrder يتوقع OrderId.

TypeScript

 

المقايضات

كنوع من المقايضة الصغيرة، ستحتاج إلى استخدام X كـ Brand. على سبيل المثال، const year = 2012 as Year عندما تقوم بإنشاء قيمة جديدة من بدائي، ولكن هذا يعادل new Year(2012) إذا كنت تستخدم كائنات القيمة. يمكنك توفير دالة تعمل كنوع من “الباني”:

TypeScript

 

التحقق من الصحة مع الأنواع المميزة

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

TypeScript

 

Readonly ليس إلزامياً، ولكن للتأكد من أن رمزك لن يغير البيانات بعد التحقق منها، يُوصى بشدة بذلك.

ملخص

الأنواع المميزة هي حل بسيط يتضمن ما يلي:

  • تحسين قراءة الكود: يجعل من الواضح أي قيمة ينبغي استخدامها في كل حجة
  • موثوقية: يساعد على تجنب الأخطاء في الشيفرة التي قد يكون من الصعب اكتشافها؛ الآن تساعدنا بيئة تطوير البرامج (و التحقق من الأنواع) على اكتشاف ما إذا كانت القيمة في المكان الصحيح
  • تحقق من صحة البيانات: يمكنك استخدام الأنواع المميزة لضمان أن البيانات صالحة.

يمكنك أن تفكر في الأنواع المميزة كنوع من النسخة من ValueObjects ولكن دون استخدام الفئات — فقط الأنواع والدوال.

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

Source:
https://dzone.com/articles/branded-types-in-typescript