یکی دیگر از ویژگی های کاربردی تایپ اسکریپت قابلیت optional chaining (زنجیره سازی اختیاری) است. فرض کنید در برنامه شما داده هایی از سمت سرور یا یک پایگاه داده یا هر منبع خارجی دیگری دریافت می شوند و شما مطمئن نیستید که خصوصیت خاصی در شیء دریافت شده وجود دارد. فرض کنید اطلاعات کاربرانی را به صورت یک شیء دریافت کرده ایم. من نام این شیء را fetchedUserData می گذارم:
const fetchedUserData = { id: 'u1', name: 'Max', job: { title: 'CEO', description: 'My own company' } };
فرض ما این است که این شیء از سمت سرور به ما برگردانده شده و مطمئن نیستیم که خصوصیت مورد نظر ما در آن باشد. در حالت عادی اگر بخواهم title را از شیء بالا console.log کنم می گویم:
console.log(fetchedUserData.job.title);
در حال حاضر اگر قسمت job از شیء fetchedUserData را کامنت کنیم، تایپ اسکریپت به ما خطا می دهد چرا که به شیء دسترسی دارد و می داند job ای وجود ندارد اما زمانی که چنین شیء ای را از سمت سرور و مثلا با درخواست AJAX دریافت کنیم با خطا روبرو نمی شویم چرا که تایپ اسکریپت نمی داند چه داده ای قرار است برایمان ارسال شود. در جاوا اسکریپت معمولی برای چنین حالتی از تکنیک زیر استفاده می کنند:
console.log(fetchedUserData.job && fetchedUserData.job.title);
یعنی ابتدا چک کرده ایم که job درون fetchedUserData وجود داشته باشد و اگر اینطور بود سپس به دنبال title می گردیم. اگر قسمت اول (یعنی fetchedUserData.job) برابر undefined باشد و به هر دلیلی وجود نداشته باشد، قسمت دوم (fetchedUserData.job.title) هیچ وقت اجرا نمی شود بنابراین از بروز خطا جلوگیری می کنیم. خوشبختانه برای انجام این کار روش بهتری در تایپ اسکریپت وجود دارد که از نسخه 3.7 به بعد در دسترس شما خواهد بود. ما می توانیم برای خصوصیتی که از آن مطمئن نیستیم از علامت سوال استفاده کنیم:
console.log(fetchedUserData?.job?.title);
با انجام این کار به تایپ اسکریپت می گوییم اگر fetchedUserData وجود دارد دنبال job بگرد و اگر job را پیدا کردی به دنبال title بگرد. در صورتی که job یا fetchedUserData وجود نداشته باشد، تایپ اسکریپت دیگر به دنبال title نمی گردد و از بروز خطا جلوگیری می کنیم. زمانی که این کد را به جاوا اسکریپت کامپایل کنیم، کد بالا تبدیل به چند شرط if می شود که وجود خصوصیات بالا را چک می کنند.
Nullish Coalescing یکی دیگر از قابلیت های تایپ اسکرپیت است که به ما در مدیریت داده های null یا داده هایی که معادل null هستند (nullish) کمک می کند. فرض کنید داده ای داشته باشید که ندانید null است یا undefined است یا واقعا داده معتبری درون خود دارد:
const userInput = null;
من در اینجا برای کار با داده ها userInput را به صورت دستی روی null قرار داده ام اما شما فرض کنید که این داده از جایی مثل سرور API یا DOM یا هر منبع خارجی دیگری می آید و ما نمی دانیم userInput دقیقا درون خود چه چیزی دارد. حالا ما userInput را از API یا DOM یا هر جای دیگری دریافت کرده ایم و می خواهیم آن را درون یک متغیر ذخیره کنیم.
در بسیاری از اوقات ما نمی خواهیم مقادیر null را جایی ذخیره کنیم چرا که به درد ما نمی خورند. ما باید راهی پیدا کنیم که بگوییم اگر داده ما null است آن را ذخیره نکن بلکه کار دیگری را انجام بده (مثلا داده پیش فرض خودمان را ذخیره کنیم). برای انجام این کار می توان گفت:
const storedData = userInput || 'DEFAULT';
اگر داده اول (userInput) برابر null باشد، رشته DEFAULT در storedData ذخیره خواهد شد. مشکل این روش اینجاست که اگر مقدار userInput به جای null یا undefined یک رشته خالی باشد، آن رشته خالی هم false حساب شده بنابراین باز هم DEFAULT را ذخیره می کنیم. برای تست این مسئله می توان گفت:
const userInput = ''; const storedData = userInput || 'DEFAULT'; console.log(storedData);
در حال حاضر اگر به کنسول مرورگر خود بروید، رشته DEFAULT برایتان چاپ خواهد شد که یعنی مقدار userInput (رشته خالی) برابر با false در نظر گرفته می شود. اگر سیستم مد نظر شما باید به این شکل رفتار کند، دستور بالا مشکلی ندارد اما اگر سیستم مد نظر شما نباید رشته خالی را برابر false در نظر بگیرد (به طور مثال داده خالی را نیز از کاربر قبول می کنید) کد بالا مشکل ساز می شود. راه حل این مشکل استفاده از اپراتور ؟؟ است:
const userInput = ''; const storedData = userInput ?? 'DEFAULT'; console.log(storedData);
اپراتور بالا (؟؟) اپراتور nullish coalescing نام دارد و تنها زمانی رشته DEFAULT را ذخیره می کند که مقدار userInput واقعا برابر null یا undefined باشد، نه مقادیری که ممکن است برابر false تفسیر بشوند. اگر کد بالا را ذخیره و به مرورگر بروید، به جای رشته DEFAULT یک رشته خالی در کنسول مرورگر خود مشاهده خواهید کرد.
با این قسمت، به پایان این فصل رسیدیم. در این فصل با کلاس ها، interface ها و تایپ های پیشرفته ای آشنا شدیم. تعداد قابلیت هایی که در این فصل ارائه کردیم بسیار زیاد است بنابراین حتما در آینده پروژه ای خواهیم داشت که در آن از این قابلیت ها استفاده می کنیم. البته هنوز دو فصل تا پروژه اصلی ما باقی مانده است که مربوط به Generics و Decorator ها می باشد اما پس از اتمام آن ها به سراغ یک پروژه Drag and Drop می رویم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.