<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Amirabbas</title><link>https://virgool.ir/feed/@amirabbasjalali</link><description>just a cracked skull</description><language>fa</language><pubDate>2026-11-11 14:23:08</pubDate><image><url>https://files.virgool.ir/upload/users/14467/avatar/rRhjvy.jpeg</url><title>Amirabbas</title><link>https://virgool.ir/@amirabbasjalali</link></image><item><title>این Exclude چی میگه؟</title><link>https://virgool.ir/@amirabbasjalali/what-the-exclude-zcrzqbtoz0hi</link><description>احتمالا اگر جزو TS باز ها باشید، حتما به Exclude برخوردید و ازش استفاده کردید.برای دوستانی که تازه شروع کردند و یا درحد کمی با TS آشنا هستند،این exclude میاد از union ورودی، عضو هایی که میخواهیم نباشه رو حذف میکنه.یه چیزی مثل Omit که برای پراپتری های object type ها داریم ولی برای union ها.در قالب یک مثال بخوام بگم، اگه از union ای به اسم A بخواهیم &#39;c&#39; رو حذف کنیم (تا این برسیم به &#39;a&#39; | &#39;b&#39;) میتونیم بگیم:ولی خوب بحث من راجب کاری که این تایپ میکنه نیست، چون اکثرا راجبش میدونید و کلا فهمش چیز سختی نیست،بحث من راجب definition این تایپ هست. تاحالا شده به definition این تایپ نگاهی کرده باشید؟موقعی که اولین بار این تایپ رو دیدم، عکس العملم این بود که &#34;چی شد!؟&#34;.اولین چیزی که چشمتون رو باید گرفته باشه اینه که ظاهرا چیزی که اون بالا براش نوشتن با چیزی که اون پایین هست (signature اش) نمیخونه.ترجمه توضیحش میشه &#34;از تایپ T حذف کن تایپ هایی را که قابل assign شدن به U هستند&#34;،‌ درسته، این دقیقا چیزی هست که میخواهیم، ولی بذارید کد نوشته شده زیرش رو هم با خودمون بخونیم.احتمالا قسمت اول کد (حالت اول شرط) رو اینطوری میخونید، &#34;اگر تایپ T ما assignable بود به تایپ U به ما never ریترن کن&#34;.تا اینجا منطقیه چون اگه تایپ T که میخواهیم ازش U هارو حذف کنیم خودش زیرمجموعه یا برابر U بود اصولا تایپ خروجی باید &#34;هیچ&#34; بشه، مثل این میمونه بگیم بیا از &#39;a&#39; | &#39;b&#39; | &#39;c&#39; | &#39;d&#39; ،&#39;a&#39; | &#39;b&#39; | &#39;c&#39; رو حذف کن خوب چیزی ازش نمیمونه.ولی حالت دوم شرط هست که عجیبه، اینجوری میخونیم که &#34;اگه زیر مجموعه اش نبود، همون T رو خروجی بده&#34;...چی شد؟با این تفسیر B:باید بهمون &#39;a&#39; | &#39;b&#39; | &#39;c&#39;  رو بده دیگه چون &#39;a&#39; | &#39;b&#39; | &#39;c&#39;  زیرمجموعه خود &#39;c&#39; نیست که بخواد never ریترن کنه پس باید خودشو ریترن کنه، حالت دوم داره اینو میگه، ولی خوب میدونیم خروجی برابر &#39;a&#39; | &#39;b&#39; هست.اینجاست که نکته tricky ماجرا میاد وسط، در تایپ اسکریپت وقتی می‌آییم union ای رو به عنوان generic به تایپی میدیم، شرط داخل اون تایپ به ازای هر عضو union اعمال میشود نه به ازای کل union.یعنی برای ‌B انگار  همچین اتفاقی افتاده : دا درواقع توی داکیومنت زبان هم خیلی مختصر به این موضوع اشاره شده.البته جالب است بدونید که این اتفاق فقط داخل conditional type نمیوفته، همین حالت رو داخل template literal types  هم داریم، یعنی مثلا:</description><category>Amirabbas</category><author>Amirabbas</author><pubDate>Wed, 16 Aug 2023 12:54:36 +0330</pubDate></item><item><title>خفن شدن با فقط %1 بهتر شدن؟</title><link>https://virgool.ir/@amirabbasjalali/getting-better-by-one-percent-iafpneouuzeh</link><description>سورسجیمز کلیر در کتاب عادات اتمی اش میگوید &#34;اگر هر روز فقط %1 بهتر شوید در پایان سال 37 برابر بهتر میشوید&#34;، این دقیقا یعنی چی و چقدر ممکن هست؟زنگ ریاضیبرای اولین بار که این جمله رو خونده بودم سوال شده بود، چرا هر روز 1% بهتر شدن میشه برابر ۳۷ برابر بهتر شدن؟ رفتم سراغ ریاضی .امروز %1 بهتر شدم، فرض شما برای ورزش روز اول 100 تا شنا میرید،‌ اگر روز بعد هم همون 100 تا رو برید، شما %100 روز اول شنا رفتید، اما اگر روز بعد 101 شنا برید، شما %101 روز اول شنا رفتید این میشه همون پیشرفت %1.بیاییم درصد رو در قالب اعشار بنویسیم، 100% میشه همون 1 (100/100) و %1 میشه همون 0.01 (1/100).حالا مسئله بالا رو اینجوری تعریف کنیم که من 1 دیروز هستم. امروز 0.01 بهتر میشه پس میشم 1.01. این میشه روندمون این رو به یاد داشته باشید.اصل مطلب روز دومه، شاید فکر کنیم که خوب فردا %2 بهتر میشیم دیگه ولی اینطور نیست، ما یک درصد نسبت به روز قبل بهتر خواهیم شد.روز دوم هم باز باید از روز قبل 0.01 بهتر شویم، برای محاسبه 1.01 هه روز قبل این مقدار رو در روز قبل ضرب میکنیم:1.01 * 1.01 = 1.0201خوب این شد روز دوم، روز سوم هم همین روند رو ادامه میدیم 1.01 * 1.01 * 1.01 = 1.030301و خوب اینو میبینیم که به تعداد روز ها این اعداد در هم دارند ضرب میشوند پس برای یک سال حدودا میگیم:37 ≈ 365 ^ 1.01خوب که چی؟اینارو نگفتم که درگیر ریاضیتون کنم (هرچند جدا از اینا برا خودم جالب بود گفتم شاید برای شما هم جالب باشه).دلیل اصلی این بود که شمار رو با مفهوم یک درصد بهتر شدن آشنا کنم.این عجیب نیست؟به مقاله ای خوردم که عنوانش بود The Myth of The 1% Better Every Day Theory،‌ به فارسی تقریبا میشه &#34;خرافه ای به نام تئوری هر روز یک درصد بهتر شدن&#34;.مطالب جالبی داشت ولی جالب ترینش قسمتی بود که این تئوری رو به شکل جالبی به چالش میکشهاو با یک مثال از زندگی خودش شروع میکنهمیگه که &#34;من تصمیم گرفته بودم هر روز تا شنا برم&#34;بعد روی این کارش، قضیه یک درصد بهتر شدن رو اعمال میکنه و بنظرتون چی میشه؟ غیرممکن میشه.سورساستدلالی که میکنه که خوب من اگه رویه یک درصد بهتر شدنو ادامه بدم تا روز آخر سال باید 466 تا بتونم برم و البته اینجا تموم نمیشه چون شاید بخوام یه سال دیگه ادامه بدم، و اینطوری خوب تعدادش خیلی خیلی زیاد میشه.خوب راه حل چیه؟ما یک نمودار linear داریم و یک exponential.نمودار linear همون نمودار خطی هست که میتونه مثالش تابع f(x) = x باشه:سورسنکته مهم این تابع اینه که این تابع بصورت جمع کار میکنه، یعنی هر روز یک مقدار مشخص بریم جلو، اگه بخواهیم مسئله پیشرفت یک درصدی رو روش اعمال کنیم ایطوری میشه که:ما اگر هر روز فرض $1 دربیاریم روز روز اول $1 داریم و در روز دوم $2 درمیاریم (%100 مقدار حاضر) و بعدش روز سوم $3 (%50 مقدار حاضر) و اینو همینطور ادامه بدیم همینطور مقدار پیشرفت کم میشه تا برسه به روز 365 ام که مقدار پیشرفت خیلی کم شده (میشه تقریبا %0.02) که خیلی بده.نمودار exponential یا همون نمایی مثلا f(x) = e^x باشه: اینجا بحث فرق میکنه، اینجا به جای جمع با ضرب سر و کار داریم، هر بار جلو رفتن ما در یک مقدار مشخص ضرب میشه، برای این مثالی نمیزنم چون مثالش همون بخش زنگ ریاضی که گفتم خودش نمونه یک تابع با مشخصات f(x) = 1.01^x هست و گفتم اگه ادامه اش بدیم چی میشه و چه مشکلاتی درست میکنه و چقدر از واقعیات دور هست.در مقاله دیگری که به این موضوعات پرداخته (اینکه این نمودار هارو وارد بازی کردم رو بخاطر این بود که داخل همین مقاله خونده بودمشون و بنظرم مهم بود، حتما یه سر بهش بزنید اگه دوست دارید بهتر این موضوع رو درک کنید) مثالی از یک نمودار ممکن برای ماها میزنه، نمونداری که شکل S داره که بهش تابع سیگموئید: این بیانگر یه ترکیبی از دو تابع بالاست، شروعی نمایی و میلی خطی و مهم تر از همه نقطه ای هست که پیشرفت دیگه سرعت چندانی نداره، رسیدن به اون نقطه بیانگر محدودیت انسان هاست‌.ما تا یه جایی، جای پیشرفت داریم، انسان ها تا یه سرعتی میتوانند بدوند، انسان ها تا یه تعدادی میتوانند شنا  بروند، حتی اگر هر روز بتوانید یکم سرعتتان را بیشتر کنید بلاخره به محدودیت خود میرسیم، و پیشرفت ها مثل این تابع به افقی شدن (جزئی تر شدن) ادامه میدهند، مهم این است که بدانیم پیشرفت تابعی خطی یا حتی نمایی نیست.الان چی کنیم؟آیا باید این شعار رو دور بیندازیم؟ من اینطور فکر نمیکنم، این شعار هرچند از نظر ریاضی به جای درستی ختم نمیشه، ولی ایده کلیش چیز ارزشمندی هست، ما نگفتیم پیشرفت چیز بدی هست، آقا نمودار بالا رو اصلا ببینید، نمودار داره به سمت بالا حرکت میکنه، این چیز خوبیه خوب، ما صرفا گفتیم که این نمودار از یه حدی هم نمیتونه عبور کنه، همین، کسی که هر روز ۱۰۰ تا شنا میره بدنش خیلی با اونی که ۵ تا هم نمیتونه بره فرق میکنه، خود ۱۰۰ تا شنا رفتن هم نوعی پیشرفت هست، آقا ما داریم اینجا زحمت میکشیم ‌:))شاید بعد یه مدت پیشرفت ها کوچک تر بشوند ولی به این معنی نیست که باید قطعش کنیم، راجب مواد مخدر صحبت نمیکنیم که بگیم آقا انقدر زدم و انقدر دیگه رو بدم جواب نمیده باید بریم یه پله بالاتر، ورزش کردن ما خودش سودشو میرسونه و به اصطلاح رو بدن جواب میده، اگر همین این ۱۰۰ تا رو  قطع کنی پسرفت میاد تو بازی، و بله، ۱۰۰ تا رفتن از ۵۰ تا رفتن خیلی بهتره، اینکه بگیم یه پارچ رو بیشتر از یه حدی نمیشه پر کرد نفی خود پر کردن نیست، اینارو گفتیم که حد و حدود رو مشخص کنیم و دوتا نکته ازش دربیاریم1) تا جایی که ممکن هست و میتونی، درحال پیشرفت باش.2) اولیت بندی داشته باش و وقتت رو صرف چیزهای مهم کنآیا میخوای بیشتر شنا بری؟ سعی کن هر از چند گاهی تعدادشو بیشتر کنی، زمان گذشت و الان داری روزی ۱۰۰ تا شنا میری، آیا باید باز هم بیشترش کنی؟ چرا که نه ولی باید تقسیم بندی داشته باشی و مثلا صبح ۱۰۰ تا بری بعدالظهر n تای دیگه و...،‌ آیا حاضری انقدر وقت روش بگذاری؟ آیا انقدر برات مهم هست؟ و یا حتی سوالی مهم تر اینکه اصلا من هدفم چیست؟ شنا رفتن یا فرد سالمی شدن؟‌ اگر هدفتون سلامتی هست و یا ورزشکار شدن خوب کلی ورزش دیگه هم هست که روی جاهای دیگه بدن کار میکنه و میتونید امتحانشون کنید (اینجا درواقع دارم راجب همون مسئله هویتی شدن عادات صحبت میکنم که خود جیمز راجبش صحبت کرده).اگر برای مثال این موضوع پیشرفت را در حیطه برنامه نویسی ببریم فرق بین مثال های بالا و این رو میبینیم،‌ برنامه نویسی خیلی کلی هست، کلی شاخه درش نهفته هست، مثل فرق بین ورزش و رفتن n تا شنا در روز هست، رفتن شنا زیر مجوعه ای از ورزش هست، یکی جزئی تر و دیگری کلی تر هست.اینجا دوباره همون مسئله هویت هست که ما اگر روی کلیت ها بخواهیم کار کنیم، پیشرفت ها ریز تر و محدودیت ها کمتر میشه و البته possibility ها (حالات ممکن) بیشتر.اینجاست که باید این چیزهارو باهم بالانس کنیم، نکته دوم رو در نظر بگیریم و سوال مهم رو بکنیم که ما در چه چیزی میخواهیم چقدر بیشرفت کنیم؟مثلا وقتی هدفت  یک برنامه نویس خوب شدنه نمیای وقتتو هم صرف خوندن راجب طرز کار کامپایلر ها بکنی هم صرف یادگیری HTML و CSS برای یافتن شغل در حیطه فرانت‌ اند، اول تصمیم میگیری که میخوای اولیتتو روی کدوم بذاری، اگر روی دومی بذاری دیگه وقت زیادی رو صرف یادگیری راجب اولی نمیکنی، صرفا درحد نیاز و یا اگر گییک باشی خوب شاید بیشتر ولی باز هم اولیت با دیگری هست اصولا وقت بیشتری رو صرفش میکنیمیبینید که نیاز نیست حتما هر روز یک درصد بهتر، اصلا بعید میدونم هدف جیمز هم این بوده باشه که باید حتما  هر روز یک درصد بهتر شوید، خیر، یک روز میتونی بیشتر از یک درصد بهتر بشی یک روز اصلا پیشرفتی نداشته باشی و در آخر هم دیدیم که اصلا یه حد و حدودی هم داریم،‌ جیمز صرفا میخواست قدرت پیشرفت های اتمی رو نشون بده وگرنه قانونی وضع نکرد.</description><category>Amirabbas</category><author>Amirabbas</author><pubDate>Sun, 13 Aug 2023 10:48:04 +0330</pubDate></item><item><title>درست fetch کن</title><link>https://virgool.ir/@amirabbasjalali/درست-فچ-کن-iqjzsjtg2tit</link><description>اکثریت از فانکشن fetch که مرورگر در دسترستون میذاره استفاده کردید (البته بحثم فقط با اون نیست بلکه با بقیه کتابخونه هایی مثل Axios هم هست)بذارید کار رو با یک مثال شروع کنیم:(اگر اون declare براتون جدیده به طور خلاصه اینجوری بخونیدش که داریم به ts میگیم&#34;ما یک url از تایپ string داریم، کار نداشته باش که کجا تعریفش کردیم، فقط هست&#34;)بنظرتون مشکل این تابع چیه؟ این تابع دوتا مشکل اساسی داره یکیش رو میگم فعلامشکل اول:شاید چیز عجیبی به ذهنتون خطور نکنه چون این اپ واقعا ساده است و واقعا این مشکل ها توی این scale ایرادی نداره، بلکه حتی حل کردنشون میتونه وقت الکی بگیره و complexity رو بیشتر کن.ولی ازین موضوع بگذریم، درواقع اولین مشکل اون &lt;Promise&lt;Game هست.کی گفته این تابع &lt;Promise&lt;Game میده چرا &lt;Promise&lt;string نده؟اگر همین کد روی توی  ادیتورتون بزنید بعد تایپ خروجی رو بکنید پرامیس هرچیزی که دلتون میخواد میبینید که هیچ اروری از typescript نمیگیریدمشکل اصلی اینجاست که خروجی واقعی این فانشکن &lt;Promise&lt;any هستش (‌ اگر ریترن تایپ فانشکن رو بردارید نشون میده )نمیدونم چقدر با ts آشنایی دارید و در چه سطحی هستید ولی چند تا سوال ممکنه براتون پیش آمده باشهاوکی تایپش any هست، مشکل چیه؟اول یه سوال میپرسم ما چرا از ts استفاده میکنیم؟ احتمالا میگید تا type-safety بگیریم، که بتونیم ارور هارو ببریم سمت compile-time تا runtime، که گارانتی نخوردن به ارور در رانتایم رو به حداقل برسونیم و...خوب این دقیقا داره این type-safety رو از بین میبره، کل دلیل اینکه از ts استفاده میکنیم رو از بین میبره،وقتی ندونیم تایپ خروجی چیه، ts میخواهیم چی کار؟من میتونم URL اشتباه بدم و یه چیز اشتباه بگیرمچیزی که اون URL میده هم میتونه تغییر کنه باز یه چیز اشتباه بگیریمدرسته، شاید بگیم &#34;بیخیال، کی همیچن کاری میکنه و چه زمانی ممکنه همچین اتفاقی بیوفته&#34; و این حرف غلط هم نیست، درسته، یه همچین اپ ساده ای نیازی به راه حل نداره، خیلی جاها راحت اعتماد میکنیم به API ها توی رانتایم مشکل هم خوردیم مهم نیست.ولی تو scale بالاتر هرچقدر predictability رو بالاتر ببریم بهتر هستو البتهمن فقط حرفم راجب فچ کردن نیست مشکل ما باید با چیزایی باشه که مسئولیتشون بخش Input در IO هست ولی گارانتی درستی از Input به ما نمیدن منظورم از &#34;مسئولیتشون بخش Input است&#34; به طور خلاصه (اگر بیخیال اون O که به معنی Output هست بشیم) میشه &#34;هر نوع استفاده/گرفتن چیزی از بیرون اسکوپ اپمون یا بهتره بگیم دنیای بیرون رو Input میگیم&#34;مثال زیاد هست، گرفتن تاریخ با همین ()new Data، گرفتن عدد رندوم، فچ کردن، گرفتن ورودی ترمینال، گرفتن یه المنت html از مرورگر و...بذارید یه مثال بزنمما یه ربات داریم که خوب، نمیتونه خودش تصمیم بگیره، بهش یسری عملیات میدیم۵ دقیقه دیگر برو دم دربدرب را باز کنعلی یک بسته به تو میدهددرب را ببندکنسرو را از بسته خارج کن بگذار داخل قابمه پر آب جوش آشبزخانه بعد از ۱۵ دقیقه بریز داخل ظرف و برایم بیارمشکل اینجاست اگر داخل بسته به جا کنسرو تن ماهی (چیزی که ما مخواهیم)، یک کنسرو آناناس بود (چیزی که واقعیت هست) چی؟ در اون صروت مراحل بعدی مشکل ساز میشن این مشکل دقیقا به قضیه ما مپ میشه.خونه runtime ما هست، جایی که بهش اعتماد کامل داریم، یعنی نیازی نیست چک کنیم که آیا داخل خانه آشبزخانه ای هست یا آیا دری هست یا نه درب خانه، فچ ما هست، وجود درب یه چیز مسلم هست که رانتایم گارانتی میکنه، ولی اینکه اون طرف در چه میتونه بیاد رو نه (درواقع اون طرف درب میتونه Input ما باشه)اینکه ما چیزی درمورد تن ماهی بودن کنسرو به ربات نگفتیم هم مشکل ما هست، ما میدونیم که کنسرو ماهی میخواهیم ولی به ربات نگفتیم، فقط گفتیم کنسرو در مثال خودمون هم ما میدونیم گیم میخواهیم ولی رانتایم که هیچی نمیدونه هیچ، تایپ اسکریپ هم سرش کلاه گذاشتیم، اونم با تایپی به اسم any که کارش زدن توی سر ts هست.یک تیر و دو نشان:+ حالا راه حل چیه؟- ساده است، ما باید به رباتمون بگیم داخل بسته باید یک کنسرو تن ماهی باشه.+ اینو چطوری مپ کنیم به کدمون؟ - باید parse کنیم+ یعنی چی؟- یعنی باید تک تک پراپرتی ها چک بشه.یه همچین چیزی میشه:خوب حالا آیا باید برای هر data structure ای که داشتیم اینارو دستی بنویسیم؟ نهخوشبختانه کلی کتابخونه اون بیرون هست که خیلی راحت این کارو برای ما میکنن، معروف ترین هاش شامل io-ts ،zod ،runtypes و... هستفعلا یه مثال برای پیاده سازی همین چیزی که نوشتیم با runtypes نشون میدم (البته نظر خودم روی io-ts هست)حالا شاید بگید اینجوری داریم یه schema برای ts و یه schema برای رانتایم درست میکنیم، اکثر کتابخونه های decode کردن این قابلیت رو دارن که از روی schema خودشون تایپ رو هم بسازن تو این مثال اینجوری میشه:همه چی عالی ولی اگه دقت کرده باشید توی عنوان این بند گفتم &#34;یک تیر و دو نشان&#34; و اگه یادتون باشه برای کد مثال گفتم ما با این کد دوتا مشکل داریم، مشکل اول همین بود، مشکل دوم ارور هندلینگ هستیکی از مزیت های دیگه این کتابخونه ها و کلا parse کردن به ما میدن مجبور کردن ما به هندل کردن else case هستاگه دقت کنید ما خروجی رو union کردیم چون ممکنه parse امون fail بشه و همین اضافه کردن parsing یه تیر و دو نشون زدیمحتی توی مثال ربات امون هم اینجوریه، باید مشخص کنیم اگر تن ماهی نبود، ربات چی کار کنه.یه نکته دیگه که شاید دقت کرده باشید اون price تایپش هم توی تایپ جنریت شده استرینگ شده هم توی تایپی که خودم نوشتم، این مشکلی هست که مربوط به ts میشه توی داکیومنت کتابخونه هم توضیح داده که چه مشکلی هست، ولی به طور کلی هیچ آسیبی توی رانتایم و parse کردن ما نمیزه، فقط مشکلمون اینه که تایپ درست جنریت نمیشه این runtypes تابع های دیگه ای هم روی تایپاش داره مثل validate و check میتونید اونارو هم چک کنیدنتیجه:برای فچ هامون پارسر بنویسیماز JSON.parse خالی استفاده نکنیم، خودمون هم بر اساس چیزی که میخواهیم دیتا رو پارس کنیمبه تایپ any که خروجی فانکشن هایی هستن که با Input سر کار دارن اعتماد نکنیمهمیشه else case هارو در نظر بگیریمبه رباتمون اطلاعات دقیق و کامل بدیم و چیزی رو تو ذهنمون نگه نداریم</description><category>Amirabbas</category><author>Amirabbas</author><pubDate>Mon, 22 Aug 2022 23:35:34 +0430</pubDate></item></channel></rss>