نکات و ترفندهای تایپ اسکریپت – راهنمای کاربردی
در این مقاله برخی نکات و ترفندهای مختلف مرتبط با زبان برنامهنویسی TypeScript را با هم مرور میکنیم. در ادامه 10 مورد از نکات و ترفندهای تایپ اسکریپت را ملاحظه خواهید کرد که مطالعه آن برای هر توسعهدهندهای با هر سطح از مهارت مناسب است.
1. TypeScript و DOM
زمانی که شروع به استفاده از TypeScript بکنید خیلی زود متوجه میشوید که در زمینه کار با محیط مرورگر کاملاً گزینه مناسبی محسوب میشود.
فرض کنید میخواهیم یک عنصر <input> را روی یک صفحه پیدا کنیم:
بنابراین به ما نشان میدهد که خطایی وجود دارد، زیرا در متد querySelector یک غلط املایی داریم و به جای input به دنبال inpot میگردیم. تایپاسکریپت از طریق فایل lib.dom.d.ts که بخشی از کتابخانه تایپاسکریپت است و اساساً همه چیز (شیء، تابعها، رویدادها) را توصیف میکند این وضعیت را مدیریت میکند. بخشی از تعریف، اینترفیسی است که درون نوعبندی متد thequerySelector استفاده میشود و رشتههایی (مانند "div", "table" یا "input") را به انواع عناصر متناظر HTML نگاشت میکند:
این راهحل چندان جالب نیست زیرا تنها برای سلکتورهای عناصر ابتدایی کار میکند، اما به هر حال بهتر از هیچ است. مثل دیگر از این رفتار هوشمندانه تایپاسکریپت زمانی است که با رویدادهای مرورگر کار میکنیم:
در مثال فوق clientX. یک مشخصه موجود یا هر نوع رویداد مفروض نیست بلکه صرفاً روی MouseEvent موجود است. تایپاسکریپت نوع رویداد را بر مبنای این مقدار رشتهای "click" که نخستین آرگومان در متد addEventListener است درک میکند.
2. ژنریکهای مورد انتظار
اگر به جای یک سلکتور عنصر از هر چیز دیگری استفاده کنیم:
در این صورت HTMLELementTagNameMap نمیتواند مفید باشد و تایپاسکریپت صرفاً یک نوع Element نسبتاً مقدماتی بازگشت میدهد.
همانند querySelector در غالب موارد کاربرد این گونه است که یک تابع میتواند ساختارهای متفاوتی را بازگشت دهد و در این شرایط تعیین این که کدام یک بازگشت خواهد یافت برای تایپاسکریپت ناممکن است. در چنین حالتی با تقریب بالایی میتوان انتظار داشت که تابع مذکور نیز یک ژنریک است و میتوان نوع بازگشتی را در یک ساختار ژنریک آسان ارائه کرد:
اگر با انگولار کار کرده باشید، در این صورت مثال دیگر میتواند کلاس ElementRef باشد:
3. آیا واقعاً یافتهایم؟
میدانیم که متد (...)document.querySelector عملاً همواره یک شیء بازگشت نمیدهد. یک عنصر که با این سلکتور مطابقت پیدا کند میتواند یک صفحه نباشد و به جای شیء، یک تابع مقدار null بازگشت دهد. بنابراین دسترسی یافتن به آن شیء، مثلاً مشخصه value. ممکن است همیشه آن گونه که توضیح دادیم پیش نرود.
به صورت پیشفرض بررسیکننده نوع، مقادیر null و undefined را به هر نوعی قابل انتساب می داند. این وضعیت را میتوان امنتر ساخت و این رفتار را با افزودن بررسیهای سختگیرانه null در فایل tsconfig.json محدودتر کرد:
تایپاسکریپت، با استفاده از تنظیمات فوق، در صورتی که تلاش کنید به مشخصه روی یک شیء که احتمال دارد null باشد، دسترسی یابید اعتراضی نخواهد کرد و در مورد وجود آن شیء از طریق قرار دادن آن بخش درون شرط زیر اطمینان پیدا میکنید:
کاربردهای رایج دیگر به جز querySelector به صورت متد Array.find است که نتیجه آن احتمالاً undefined است. در واقع ما همواره آن چه را به دنبالش هستیم نمییابیم.
4. اعلام مقدار به تایپاسکریپت
در بخش قبلی بررسیهای سختگیرانه null را تعریف کردیم و بدین ترتیب تایپاسکریپت در مورد مقادیر مختلف با احتیاط بیشتری برخورد میکند. از سوی دیگر برخی اوقات با اطلاع کلی صرفاً میدانیم که یک مقدار قرار است تعیین شود. در چنین کاربردهای احتمالی میتوان از عملگر «عبارت پست فیکس» (post-fix expression) استفاده کرد.
5. در هنگام مهاجرت به تایپاسکریپت
در اغلب موارد زمانی که یک کدبیس قدیمی دارید که میخواهید به تایپاسکریپت تبدیل کنید، یکی از بزرگترین دردسرها این است که کاری کنید id شما به قواعد TSLint بچسبد. به این منظور میتوان همه این فایلها را با افزودن کد زیر به نخستین خط هر کدام ویرایش کرد:
بدین ترتیب TSLint عملاً آنها را بررسی نمیکند. در این صورت تنها هنگامی که یک توسعهدهنده روی یک فایل قدیمی کار کند شروع به حذف این کامنت و اصلاح خطاهای صرفاً روی آن فایل میکند. از این رو ما دیگر یک انقلاب نداریم، بلکه با یک تکامل روبرو هستیم و کدبیس به تدریج اما با امنیت بهبود مییابد.
همانند افزودن انواع واقعی به کد قدیمی جاوا اسکریپت میتوانید عملاً در اغلب موارد این کار را انجام ندهید. استنباط نوع تایپاسکریپت این وظیفه را بر عهده میگیرد. در صورتی که کدی واقعاً مرتب داشته باشید یعنی نوعهای مختلفی از مقادیر را به یک متغیر انتساب داده باشید، مشکلی نخواهید داشت. اگر بازسازی کردن این کد آسان نیست میتوانید از any استفاده کنید:
اما همیشه از این راهحل به عنوان آخرین چاره استفاده کنید چون استفاده از any در تایپاسکریپت چندان پسندیده نیست.
6. محدودیتهای بیشتر نوع
گاهی اوقات تایپاسکریپت نمیتواند نوع را استنباط کند. رایجترین کاربرد یک پارامتر تابع است:
تایپاسکریپت به صورت درونی نیاز به انتساب برخی انواع به param دارد و از این رو از any استفاده میکند. از آنجا که میخواهیم استفاده از any را به کمترین مقدار ممکن برسانیم معمولاً توصیه میشود که این رفتار را با تنظیمات tsconfig.json دیگری محدود بکنیم:
متأسفانه ما نمیتوانیم نوعی کمربند ایمنی قرار دهیم چون آن کار به نوعبندی صریح روی نوع بازگشتی تابع نیاز دارد. بنابراین اگر به جای function fn(param): string نوع یعنی (function fn(param را فراموش کنیم، تایپاسکریپت توجهی به نوع بازگشتی نخواهد داشت یا حتی اگر هر چیزی را از تابع بازگشت دهیم متوجه نخواهد شد. به بیان دقیقتر نوع بازگشتی را از هر چه که بازگشت مییابد یا نمییابد استنباط میکند.
خوشبختانه TSLint در این موارد به کمک ما میآید. با استفاده از قاعده typedef می توان انواع بازگشتی مورد نیاز را تولید کرد:
این ایده بهتری به نظر میرسد.
7. محافظان نوع
هنگامی که یک مقدار دارید که میتواند چند نوع داشته باشد باید، این نکته را در الگوریتم خود لحاظ کنید تا انواع مختلف را از هم متمایز کنید. نکته در مورد تایپاسکریپت این است که این منطق را درک میکند.
8. نکتهای دیگر در مورد ژنریکها
فرض کنید این نوع از سازه کاملاً عمومی را داریم:
شما میخواهید از آن در اپلیکیشنهای مختلف برای نمونه جهت ذخیرهسازی کتابها یا فیلمها استفاده کنید. در چنین اپلیکیشنهایی باید کاری مانند زیر انجام دهید:
این نوع از تأیید نوع ممکن است در آن کلاس چندین بار مورد نیاز باشد. کاری که میتوان به جای این کار کرد آن است که یک کلاس BookmarksService به صورت ژنریک تعریف کنیم:
اما اینک میبینیم که بیش از حد کلی شده است و باید تائید کنیم که انواعی که این کلاس با آنها کار میکند با اینترفیس Bookmark مطابقت دارد، یعنی دارای مشخصه id: string است. بنابراین اعلان بهبودیافته به صورت زیر است:
اینک در SearchPageComponent نوع را تنها یک بار تعیین میکنیم:
یک بهبود دیگر نیز برای این کلاس ژنریک وجود دارد که ممکن است مفید باشد. اگر از آن در جاهای دیگر در آن ظرفیت عمومی استفاده کنید و نخواهید <BookmarksService<Bookmark را در چنین موقعیتهایی بنویسید میتوانید نوع پیشفرض را در اعلان ژنریک ارائه کنید:
9. نوعبندی پارامترهای مسیر
این نکته اختصاص به برنامه نویسان انگولار دارد. برای ردگیری پارامترهای مسیر و دادههای resolve شده یک اینترفیس برای آنها بسازید. سپس نوعها را برای params و data در کامپوننت تأیید کنید تا دیگر نیازی به ردگیری دوباره آنها نداشته باشید.
10. ساخت اینترفیسهایی از پاسخهای API
اگر یک پاسخ بزرگ و تودرتو از API داشته باشید، نوعبندی اینترفیس متناظر به صورت دستی کار دشواری خواهد بود. این وظیفهای است که باید به وسیله رایانه اجرا شود.
چند گزینه به این منظور وجود دارند:
- http://www.json2ts.com
- http://www.jsontots.com
اما سرور اغلب این سرویسها عموماً از کار میافتند. از بین این موارد سرویس زیر عملکرد بهتری دارد:
- https://app.quicktype.io
همچنین سرویس فوق یک افزونه مناسب برای ویژوال استودیو کد دارد.
اگر این نوشته برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
- قابلیتهای کمتر شناخته شده TypeScript — راهنمای کاربردی
- راهنمای راه اندازی اکسپرس و تایپ اسکریپت — به زبان ساده
==