برنامه نویسی 5 بازدید

در این مقاله قصد داریم نوع های فرعی مبتنی بر شرط در تایپ اسکریپت و همچنین انواع «نگاشت» (Mapping) را مورد بررسی قرار دهیم. هدف ما این است که نوعی ایجاد کنیم که همه کلیدهایی را که با شرط خاصی مطابقت ندارند را از اینترفیس فیلتر کند.

به این منظور نیازی به آشنایی با جزییات نوع‌های نگاشتی وجود ندارد. کافی است بدانید که تایپ‌اسکریپت امکان انتخاب یک نوع موجود و ایجاد تغییر اندک در آن برای ایجاد نوع جدید را به ما می‌دهد. این بخشی از «کامل بودن تورینگ» (Turing Completeness) آن است.

نوع را می‌توان به صورت تابع در نظر گرفت. هر نوع یک نوع دیگر را به عنوان ورودی می‌گیرد، روی آن نوعی محاسبات اجرا می‌کند و نوع جدیدی به عنوان خروجی تولید می‌کند. اگر با <Partial<Type یا <Pick<Type, Keys آشنا هستید، این فرایند نیز کاملاً شبیه آن است.

بیان مسئله

فرض کنید یک شیء پیکربندی دارید. این شیء شامل گروه‌های مختلفی از کلیدها مانند Ids ،Dates و functions است. این شیء می‌تواند ناشی از یک API باشد و یا از سوی افراد مختلف سال‌ها نگهداری شود تا این که کاملاً بزرگ شده باشد.

ما می‌خواهیم تنها کلیدهایی را از نوع خاص استخراج کنیم. این فرایند شبیه به این است که تنها تابع‌هایی که Promise بازگشت می‌دهند را انتخاب کنیم یا چیزی ساده‌تر مانند کلید از نوع number داشته باشیم.

ما به یک نام و تعریف نیاز داریم و از این رو از <SubType<Base, Condition استفاده می‌کنیم.

بدین ترتیب دو ژنریک تعریف کرده‌ایم که به وسیله آن SubType را پیکربندی خواهیم کرد:

  • Base – اینترفیسی است که قرار است آن را تغییر دهیم.
  • Condition – نوع دیگری است که به ما اعلام می‌کند کدام مشخصه‌ها باید در شیء جدید حفظ شوند.

ورودی

به منظور تست کردن یک شیء Person داریم که از نوع‌های متفاوتی به صورت string ،number ،Function تشکیل یافته است. این همان «شیء عظیم» ما است که می‌خواهیم فیلتر کنیم.

خروجی مورد انتظار

برای مثال SubType به نام Person بر اساس نوع رشته می‌تواند تنها کلیدهایی از نوع رشته را بازگشت دهد:

گام به گام به سوی راه‌حل

در این بخش برای مسئله‌ای که در بخش قبل مطرح شد، یک راه‌حل را به صورت گام به گام مطرح می‌کنیم.

گام 1: Baseline

بزرگ‌ترین مشکل، یافتن و حذف کلیدهایی است که با شرط ما مطابقت ندارند. خوشبختانه تایپ‌اسکریپت 2.8 دارای امکانی به نام نوع‌های شرطی است. ما به عنوان یک ترفند کوچک قصد داریم نوع پشتیبانی برای یک محاسبه آتی بسازیم.

برای هر کلید یک شرط استفاده شده است. بسته به نتیجه نام را به صورت نوع تعیین می‌کنیم یا از مقدار never استفاده می‌کنیم که فلگی برای کلیدهایی است که نمی‌خواهیم در نوع جدید ظاهر شوند. این یک نوع خاص و متضاد any است. به این نوع هیچ چیز نمی‌توان انتساب داد.

در ادامه به روش ارزیابی کد می‌پردازیم:

توجه کنید که ‘id’ یک مقدار نیست، اما نسخه دقیق‌تری از نوع string محسوب می‌شود. ما قصد داریم از آن در ادامه استفاده کنیم. تفاوت بین نوع string و ‘id’ به صورت زیر است:

گام 2: فهرست‌بندی کلیدهایی که با شرط نوع مطابقت دارند

در این مرحله کار اصلی انجام یافته است. اکنون هدف جدیدی داریم و آن گردآوری نام‌های کلیدهایی است که از اعتبارسنجی ما عبور کرده‌اند. در مورد <SubType<Person, string این مقدار برابر با ‘name’ | ‘lastName’ خواهد بود:

ما از کد مرحله قبلی استفاده کرده و تنها یک بخش دیگر به نام [keyof Base] به آن اضافه می‌کنیم.

کار این بخش آن است که رایج‌ترین انواع مشخصه‌های مفروض را گردآوری کرده و never را نادیده بگیرد چون هیچ راهی برای استفاده از آن‌ها وجود ندارد.

در کد فوق مثالی از بازگشت string | number داریم. چنان که می‌بینید در نخستین گام نوع کلید را با نام آن عوض کرده‌ایم.

اینک به راه‌حل نهایی نزدیک شده‌ایم.

ما اکنون آماده ساخت شیء نهایی خود هستیم. صرفاً از Pick استفاده می‌کنیم که روی نام‌های کلید ارائه شده می‌چرخد و نوع متناظر با شیء جدید را استخراج می‌کند.

در کد فوق Pick یک نوع نگاشت درونی است که از تایپ‌اسکریپت 2.1 به بعد ارائه شده است:

راه‌حل نهایی

اگر بخواهیم همه گام‌های فوق را جمع‌بندی کنیم باید بگوییم که ما دو نوع ایجاد کرده‌ایم که از پیاده‌سازی SubType ما پشتیبانی می‌کنند:

نکته: این صرفاً یک سیستم نوع‌بندی است. می‌توان در آن از حلقه و حتی اعمال گزاره‌های شرطی نیز استفاده کرد. برخی افراد ترجیح می‌دهند که درون یک عبارت نوع‌هایی داشته باشند:

کاربرد

کاربردهای مختلفی که این نوع‌های شرطی دارند به شرح زیر هستند:

۱. استخراج صرف انواع کلید primitive از JSON:

2. فیلتر کردن همه چیز به جز تابع‌ها:

شما می‌توانید به کاربردهای دیگر این امکان نیز فکر کنید.

این راه‌حل چه مسائلی را حل نمی‌کند؟

۱. یک سناریوی جالب این است که یک زیرنوع Nullable بسازیم

اما از آنجا که string | null نمی‌تواند به null انتساب پیدا کند کار نخواهد کرد. البته ممکن است شما ایده‌ای برای حل این مشکل داشته باشید!

2. فیلترینگ زمان اجرا

چنان که می‌دانید نوع‌ها در زمان کامپایل پاک می‌شوند. بدین ترتیب هیچ نقشی در شیء واقعی ندارند. اگر بخواهید یک شیء را به نوعی فیلتر کنید، باید کد جاوا اسکریپت برای آن بنویسید.

ضمناً استفاده از ()Object.keys روی چنین ساختارهایی توصیه نمی‌شود، زیرا نتیجه «زمان اجرا» ممکن است از نوع مفروض متفاوت باشد.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

به عنوان حامی، استارتاپ، محصول و خدمات خود را در انتهای مطالب مرتبط مجله فرادرس معرفی کنید.

telegram
twitter

میثم لطفی

«میثم لطفی» دانش‌آموخته کارشناسی ریاضیات کاربردی و شیفته فناوری به خصوص در حوزه رایانه است. وی در حال حاضر علاوه بر پیگیری همه علاقه‌مندی‌های خود در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و تولید محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار نیز با مجله فرادرس همکاری دارد.

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *