Amirabbas
Amirabbas
خواندن ۲ دقیقه·۱ سال پیش

این Exclude چی میگه؟

احتمالا اگر جزو TS باز ها باشید، حتما به Exclude برخوردید و ازش استفاده کردید.


برای دوستانی که تازه شروع کردند و یا درحد کمی با TS آشنا هستند،

این exclude میاد از union ورودی، عضو هایی که میخواهیم نباشه رو حذف میکنه.

یه چیزی مثل Omit که برای پراپتری های object type ها داریم ولی برای union ها.

در قالب یک مثال بخوام بگم، اگه از union ای به اسم A بخواهیم 'c' رو حذف کنیم (تا این برسیم به 'a' | 'b') میتونیم بگیم:

ولی خوب بحث من راجب کاری که این تایپ میکنه نیست، چون اکثرا راجبش میدونید و کلا فهمش چیز سختی نیست،بحث من راجب definition این تایپ هست.

تاحالا شده به definition این تایپ نگاهی کرده باشید؟


موقعی که اولین بار این تایپ رو دیدم، عکس العملم این بود که "چی شد!؟".

اولین چیزی که چشمتون رو باید گرفته باشه اینه که ظاهرا چیزی که اون بالا براش نوشتن با چیزی که اون پایین هست (signature اش) نمیخونه.


ترجمه توضیحش میشه "از تایپ T حذف کن تایپ هایی را که قابل assign شدن به U هستند"،‌ درسته، این دقیقا چیزی هست که میخواهیم، ولی بذارید کد نوشته شده زیرش رو هم با خودمون بخونیم.

احتمالا قسمت اول کد (حالت اول شرط) رو اینطوری میخونید، "اگر تایپ T ما assignable بود به تایپ U به ما never ریترن کن".
تا اینجا منطقیه چون اگه تایپ T که میخواهیم ازش U هارو حذف کنیم خودش زیرمجموعه یا برابر U بود اصولا تایپ خروجی باید "هیچ" بشه، مثل این میمونه بگیم بیا از 'a' | 'b' | 'c' | 'd' ،'a' | 'b' | 'c' رو حذف کن خوب چیزی ازش نمیمونه.


ولی حالت دوم شرط هست که عجیبه، اینجوری میخونیم که "اگه زیر مجموعه اش نبود، همون T رو خروجی بده"...چی شد؟

با این تفسیر B:

باید بهمون 'a' | 'b' | 'c' رو بده دیگه چون 'a' | 'b' | 'c' زیرمجموعه خود 'c' نیست که بخواد never ریترن کنه پس باید خودشو ریترن کنه، حالت دوم داره اینو میگه، ولی خوب میدونیم خروجی برابر 'a' | 'b' هست.


اینجاست که نکته tricky ماجرا میاد وسط،

در تایپ اسکریپت وقتی می‌آییم union ای رو به عنوان generic به تایپی میدیم، شرط داخل اون تایپ به ازای هر عضو union اعمال میشود نه به ازای کل union.


یعنی برای ‌B انگار همچین اتفاقی افتاده :

 دا
دا

درواقع توی داکیومنت زبان هم خیلی مختصر به این موضوع اشاره شده.


البته جالب است بدونید که این اتفاق فقط داخل conditional type نمیوفته، همین حالت رو داخل template literal types هم داریم، یعنی مثلا:

برنامه نویسیتایپ اسکریپتtypescriptjavascriptprogramming
just a cracked skull
شاید از این پست‌ها خوشتان بیاید