برای تعریف تایپ های جدید در typescript دو راه داریم:
در این مقاله میخوایم شباهت ها و تفاوت هاشون رو متوجه بشیم تا بتونیم انتخاب بهتری انجام بدیم. در خیلی از شرایط میتونن جایگزین همدیگه بشن ولی در بعضی شرایط یکیشون ارجحیت داره.
کلمه type در تایپ اسکریپت یک keyword هست که ساختار دیتا رو مشخص میکنه. type های بیسیک در تایپ اسکریپت عبارتند از:
هر کدام از این تایپ ها خصوصیات خود را دارند و برای هدف خاصی تعریف شده اند.
موضوع بعدی type alias هست که با type شروع میشه و یک اسم میگیره و بعد از علامت مساوی ساختار دیتا رو مشخص میکنه:
بیاید با یک مثال توضیح بدیم:
در مثال بالا یک type جدید داریم بنام MyNumber هم برابر با همان number است. همین طور یک تایپ User داریم که ساختار یک آبجکت را با سه مقدار id، name و email را و نوع هر مقدار مشخص میکند.
در واقع MyNumber و User تایپ جدیدی نیستند بلکه type alias هستند. یعنی تنها یک نام برای ساختاری از تایپ های اصلی هستند. به مثال زیر توجه کنید:
هر دو type alias که بالا تعریف شده اند، دو نام متفاوت برای اشاره به یک type union یکسان هستند.
در typescript یک interface قراردادی است که ساختار آبجکت را مشخص میکند تا آبجکت ها به این ساختار پایبند باشند:
این قراردادی که با interface ساخته ایم را میتوانیم به صورت type alias هم تعریف کنیم:
میخواهیم به سناریوهایی بپردازیم که استفاده از type و interface ما را به نتایج متفاوتی میرساند:
تفاوت اول: ویژگی declaration merging:
ویژگی declaration merging فقط در interface ها تعریف میشود. ما میتوانیم چند بار یک interface را تعریف کنیم. در نهایت کامپایلر typescript این تعاریف متفاوت را با یکدیگر merge میکند:
اما یک نام type alias را تنها یک بار میتوان تعریف کرد. تعریف هر type یا interface همنامی منجر به خطای کامپایلر میشود.
تفاوت دوم: ویژگی Extends vs intersection:
یک interface میتواند یک یا چند interface دیگر را توسعه دهد. این کار را توسط کلمه کلیدی extends انجام میدهد:
برای گرفتن نتیجه مشابه با type ها نیاز به اپراتور intersection داریم:
همچنین میتوانیم یک interface را بر اساس یک type alias گسترش دهیم:
نکته ای که باید به آن توجه کنیم محدودیت توسعه interface بر پایه یک type است. type alias نمیتواند union type باشد. زیرا هنگام compile time به خطا میخوریم:
همچنین میتوانیم یک type را بر پایه یک interface توسعه دهیم:
تفاوت سوم: رفع conflict هنگام گسترش type و interface
هنگام توسعه یک interface بر اساس interface دیگر، استفاده از property همنام باعث بروز خطا در کامپایلر میشود:
اما در type alias ها اتفاق دیگری می افتد. استفاده از property همنام باعث میشود type های مختلف با هم merge شوند. در این حالت به کمک typeof میتوانیم بین type های مختلف property تمایز ایجاد کنیم:
هنگام گسترش تایپ ها، اگر کامپایلر نتواند تایپ ها را merge کند خطا برمیگرداند:
در واقع یک مقدار نمی تواند هم string باشد و هم number باشد.
تفاوت چهارم: پیاده سازی کلاس ها توسط interface یا type alias
در typescript میتوانیم کلاس را بر پایه type ها و interface ها توسعه دهیم:
تنها تفاوت این است که نمی توانیم کلاس را بر پایه union type گسترش دهیم:
تفاوت پنجم: ویژگی های پیشرفته type ها
در typescript، ویژگی های متنوع و بعضا پیچیده ای برای تایپ ها در نظر گرفته شده است که در interface وجود ندارد:
شباهت ها و تفاوت های type alias ها و interface ها را بررسی کردیم. در بسیاری از موارد میتوانیم این دو را بجای همدیگر استفاده کنیم ولی در برخی شرایط امکان جایگزینی وجود ندارد و تنها یک گزینه قابل استفاده است.
به طور کلی در شرایط زیر باید از type alias استفاده کنیم:
موفق باشید :)