انواع پیشرفته در TypeScript — با مثال های کاربردی
بسیاری از افرادی که به تازگی شروع به کار با TypeScript کردهاند این عادت را پیدا میکنند که به جای همه نوعهایی که پیچیدهتر از string یا number باشند، از نوع any استفاده کنند. اما با یادگیری کاربرد انواع پیشرفته در TypeScript و همچنین انواع سفارشی میتوانید به صورت بهتری از این زبان برنامهنویسی بهره بگیرید. با سوئیچ کردن به TypeScript جهت نوشتن اپلیکیشنهای مستحکم میتوانید انواع مختلفی به کد جاوا اسکریپتتان اضافه کنید. در این مقاله به بررسی مثالهایی از کاربرد انواع پیشرفته در TypeScript و شیوه استفاده از آنها در اپلیکیشنهای React میپردازیم.
در ادامه به توضیح انواع Record ،Partial ،Required ،Pick و یک نوع سفارشی به نام Omit میپردازیم.
نوع Record
این نوع بسیار مفید داخلی TypeScript در نسخه 2.1 این زبان معرفی شده است و امکان ایجاد یک map نوعبندی شده را فراهم میسازد. بدین ترتیب میتوان اینترفیسهای ترکیبی ایجاد کرد. برای این که نوع متغیری را به صورت Record تعیین کنیم، باید یک رشته به عنوان کلید و یک نوع برای مقدار متناظر آن ارسال کنیم.
سادهترین حالت زمانی است که مقدار شما به صورت String است:
1const SERVICES: Record<string, string> = {
2 doorToDoor: "delivery at door",
3 airDelivery: "flying in",
4 specialDelivery: "special delivery",
5 inStore: "in-store pickup",
6};
این کار ممکن است ساده به نظر برسد، اما روش نوعبندی سادهای در کدنویسی روزمره در اختیار شما قرارمی دهد. یکی از رایجترین حالتها زمانی است که Record در یک اینترفیس به منظور یک گزاره تجاری استفاده میشود که در یک دیکشنری به صورت جفتهای کلید/مقدار نگهداری میشود. این مدل میتواند نماینده یک مجموعه از ثابتها، رویدادها، دادههای کاربر، درخواستهای حملونقل، بلیتهای سینما و موارد دیگر باشد. در مثال زیر ما یک مدل برای محصولاتی ایجاد میکنیم که کاربر میتواند به سبد خرید خود اضافه کند:
همان طور که میبینید امکان تکمیل خودکار ادیتور به ما کمک میکند که یک شیء نوعبندی شده تعریف کنیم و متغیری را دارای یک نوع خطا معرفی میکند، زیرا همه مشخصههای آن تعریف نشدهاند.
ضمناً Typescript امکان ایجاد یک شیء خالی برای برخی شکلهای تعریفشده و سپس مقداردهی آن با مشخصهها را نمیدهد، اما در اینجا Record به نجات ما میآید.
امکان استفاده از یک string enum به عنوان کلید برای نوع Record نیز وجود دارد. برای نمونه ما از ErrorsEnum برای حفظ و دسترسی به مقادیر خطای احتمالی (پیامها) استفاده میکنیم.
در ادامه به بررسی شیوه استفاده از بهبود نوع در زمان کار با کتابخانه Material-UI میپردازیم. شما میتوانید استایلهای سفارش را با نمادگذاری CSS-in-JS اضافه کنید و آنها را از طریق withStyles تزریق کنید. بدین ترتیب میتوانید استایل را به صورت یک تابع که یک theme به عنوان آرگومان میگیرد تعریف کنید و className آتی را با استایلهای متناظر بازگشت دهید. همچنین باید نوعی برای این تابع تعریف کنید:
شاید متوجه شده باشید که افزودن این as CSSProperties برای همه شیءهای استایل کمی آزاردهنده است. به طور جایگزین میتوانید از مزیت نوع Record استفاده کرده و یک نوع برای تابع styles تعریف کنید:
اکنون میتوانید از آن به صورت امن در هر کامپوننتی استفاده کنید و از دردسرهای نوع مشخصههای CSS در استایل های خود رها شوید.
Partial و Required
نوع Partial موجب میشود همه مشخصهها در شیء به صورت optional باشند. این وضعیت در موارد زیادی به کمک شما میآید، مثلاً هنگامی که با دادههایی سر و کار دارید که یک کامپوننت میتواند رندر کند، اما میدانید که دادهها ممکن است در زمان mount شدن واکشی نشده باشند:
همچنین میتوانید از Partial برای تعریف برخی props به صورت props پیشفرض برای کامپوننت خود استفاده کنید:
به طور عکس نوع داخلی Required که در تایپاسکریپت نسخه 2.8 معرفی شده است، موجب میشود که همه مشخصههای شیء توصیفشده به صورت الزامی درآیند:
یکی از کاربردهای Required در سلکتورها است. گاهی اوقات میخواهیم از یک شیء تو در تو، یک سلکتور برای یک مشخصه بسازیم و میدانیم که در زمان فراخوانی سلکتور این مشخصه تعریف خواهد شد. این کار با استفاده از نوعبندی میسر میشود:
این کار شبیه به نوعی تقلب به نظر میرسد و در صورتی که شروع به ارثبری مشخصههای الزام شده از انواع اختیاری بکنید موجب خطا میشود، پس باید مراقب باشید.
شاید احمقانه به نظر برسد، اما موقعیتهایی که در آن کدی به صورت خودکار تولید میشود و همه اینترفیسهایی که در اختیار دارید به صورت Partial هستند و همه عناصر UI تنها به مشخصههای Required نیاز دارند، نادر نیست. بدین ترتب باید شروع به بررسی همه شیءهای تودرتوی روی undefined بکنید.
Pick و Omit
آیا تاکنون تلاش کردهاید یک نوع را به این دلیل که کلاس بعدیتان به دسته خاصی از مشخصهها نیاز ندارد، محدود کنید؟ شاید هم در فرایند ریفکتور کردن به این نقطه رسیده باشید و تلاش کرده باشید که یک بخش از سیستم را به روش جدیدی توزیع کنید. نوعهای مختلفی وجود دارند که میتوانند به حل این مشکل کمک کنند.
Pick به شما کمک میکند که از یک اینترفیس قبلاً تعریفشده استفاده کنید، اما از آن شیء تنها کلیدهایی که مورد نیاز هستند را اخذ میکند.
Omit نوعی است که از قبل در بخش lib.d.ts در Typescript تعریف نشده است، اما تعریف کردن آن با استفاده از Pick و Exclude کار دشواری نیست. این نوع مشخصههایی را که نمیخواهید از یک اینترفیس اخذ کنید، از آن جدا میکند.
در دو تصویر زیر، ProductPhotoProps شامل همه مشخصههای Product به جز نام و توضیح است:
یک مثال عملی از چنین موقعیتی در زمان ریفکتور کردن یک فرم بزرگ است که وابستگیهای فیلد پیچیدهای دارد. در این پروژه، نوعی به صورت FormProps وجود دارد که فیلد خطاها در آن گنجانده شدهاند. با توجه به این که خطاها برای یک کامپوننت فرزند نخست غیرضروری هستند، اما همچنان برای آنها که در لایه دوم قرار دارند لازم هستند، میتوانیم بخشی از فیلدها را به استثنای خطاها برای یک اینترفیس جدا برداریم و بدین ترتیب به خوبی کار میکند.
البته روشهای مختلفی برای ترکیب نوعها و تعریف رابطه آنها وجود دارد اگر شروع به تجزیه یک شیء بزرگ به قطعات کوچکتر بکنید، شاید مشکل را از طریق حذف مشخصهها از یک شیء در طرف دیگر حل کنید. به جای آن میتوانید نوعها را بسط دهید.
بسط نوع/اینترفیس
زمانی که یک اینترفیس را بسط میدهید، همه مشخصههای توصیفشده در اینترفیس/نوع مبدأ در اینترفیس حاصل موجود خواهند بود. در ادامه میبینیم که چگونه میتوانیم اینترفیسهای کوچک را با هم ترکیب کنیم و اینترفیسی مرتبط با کار مورد نظر خود بسازیم:
این روش چندان کارآمد نیست، زیرا باید شکل شیءهای خود را از قبل تصور کنید. از سوی دیگر سریع و آسان است و موجب میشود که برای ساخت پروتوتایپ یا ساخت UI سادهای مانند رندر کردن دادهها در بلوکهای صرفاً خواندنی مناسب باشد.
سخن پایانی
در این مقاله به بررسی برخی از رایجترین انواع از پیش تعریفشده تایپاسکریپت پرداختیم و نمونه کدهای واقعی برای هر کدام معرفی کردیم. پروژهای که استفاده شده است صرفاً یک دمو است، اما این نوعها دستکم در همه اپلیکیشنهای واقعی نیز کار میکنند. امیدواریم این مقاله برای شما مفید بوده باشد و موجب شود تشویق شوید روشهای جدید کدنویسی را امتحان کنید. در این ریپو (+) میتوانید اغلب مثالهای مرتبط را مشاهده کنید.
با این حال باید یک نکته دیگر در مور نوعبندی استاتیک بگوییم. در اغلب موارد هنگامی که یک فناوری جدید را بررسی میکنیم یا با چالشی در طی توسعه یک قابلیت مواجه میشویم، شروع به حل مسئله فنی میکنیم و ممکن است هدف نهایی را فراموش کنیم. نوعبندی استاتیک هدف کار شما نیست و صرفاً یک ابزار است. اگر این مسئله به موضوع مرکزی پروژه شما تبدیلشده است، نشان میدهد که از مسیر خارج شدهاید. به تعادل بین بخشهای تجاری/تکنیکی اپلیکیشن خود توجه داشته باشید و از کدنویسی خود لذت ببرید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
- راهنمای راه اندازی اکسپرس و تایپ اسکریپت — به زبان ساده
- کاربرد ژنریک و Augmentation در تایپ اسکریپت — از صفر تا صد
==