<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رضا میرزاپور</title>
        <link>https://virgool.io/feed/@Reza.mirzapour</link>
        <description>توسعه دهنده وب</description>
        <language>fa</language>
        <pubDate>2026-06-08 01:00:54</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/58266/avatar/tb1sPu.jpg?height=120&amp;width=120</url>
            <title>رضا میرزاپور</title>
            <link>https://virgool.io/@Reza.mirzapour</link>
        </image>

                    <item>
                <title>نوشتن چند Utility Type پرکاربرد در Typescript</title>
                <link>https://virgool.io/@Reza.mirzapour/%D9%86%D9%88%D8%B4%D8%AA%D9%86-%DA%86%D9%86%D8%AF-utility-type-%D9%BE%D8%B1%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-%D8%AF%D8%B1-typescript-thwqdmzbgmwu</link>
                <description> سلام دوستان امیدوارم حالتون خوب باشه. این اولین مقاله من تو ویرگوله که درباره نوشتن یوتیلیتی تایپ های کاستوم در تایپ اسکریپته. اولین مقاله رو با تایپ اسکریپت شروع کردم چون این روزا طرفدارای زیادی تو سراسر دنیا پیدا کرده ولی مطلب فارسی در موردش خیلی کمه و یه جورایی داره در حقش احجاف میشه. خب حرفای حاشیه ای بسه بریم یه مقدمه کوچیک و بعدش هم مطلب اصلی.تایپ اسکریپت بطور built-in دارای تعدادی utility type پابه ای هستش و پیاده سازی سایر یوتیلیتی تایپ های کاستوم رو به عهده برنامه نویس ها گذاشته. ما هم قراره تو این مطلب چند تا یوتیلیتی تایپ سفارشی پرکاربرد رو پیاده سازی کنیم ولی پیش نیازش دونستن جنریک ها و چند یوتیلیتی تایپ built-in مثل Required, Partial, Pick و Omit هستش که قبل از شروع مختصر درباره شون توضیح میدم.فلسفه و منطق به وجود اومدن جنریک ها نوشتن تابپ های resusable بوده، به این صورت که یک تایپ بتونه بعنوان ورودی یک یا چند تایپ دیگه رو بگیره و تایپ جدیدی رو بهمون برگردونه. تو مثال زیر اینترفیس ServerResponse بعنوان ورودی تایپ T رو میگیره و نوع پراپرتی data رو برابر با آرایه ای از T ها قرار میده.interface ServerResponse&lt;T&gt; {
    message: string;
    hasError: boolean;
    data: T[]
}حالا که با مفهوم جنریک آشنا شدیم کمی با یوتیلیتی تایپ های built-inیی که بالا بهشون اشاره کردیم آشنا میشیم1. Required&lt;T&gt;به عنوان ورودی یک تایپ رو میگیره و پراپرتی های اون رو به حالت اجباری در میاره. در کد زیر RequiredUserType و RequiredUserInterface با هم معادلندtype RequiredUserType = Required&lt;UserInterface&gt;

interface RequiredUserInterface {
    email: string;
    firstName: string;
    lastName: string;
    age: number;
    phone: string;
    address: string
}2. Partial&lt;T&gt;تایپ T رو میگیره و پراپرتی های موجود اون رو به حالت Optional درمیاره. در کد زیر PartialUserType و PartialUserInterface با هم معادلند.type PartialUserType = Partial&lt;UserInterface&gt;

interface PartialUserInterface {
    email?: string;
    firstName?: string;
    lastName?: string;
    age?: number;
    phone?: string;
    address?: string
}3. Pick&lt;T, P extends keyof T&gt;به عنوان ورودی تایپ و unionی از پراپرتی های موجود در اون تایپ رو میگیره و تایپ خروجی، تایپیه که شامل اون پراپرتی هایه. در کد زیر PickUserType و PickUserInterface با هم معادلند.type PickUserType = Pick&lt;UserInterface, &#039;email&#039; | &#039;phone&#039;&gt;

interface PickUserInterface {
    email: string;
    phone?: string;
}4. Omit&lt;T, P extends keyof T&gt;به عنوان ورودی تایپ و unionی از پراپرتی های موجود در اون تایپ رو میگیره و تایپ خروجی، تایپیه که شامل اون پراپرتی نباشه. در کد زیرOmitUserType و  UserInterface باهم معادلند.type OmitUserType = Omit&lt;UserInterface, &#039;firstName&#039; | &#039;lastName&#039;&gt;

interface OmitUserInterface {
    email: string;
    age: number;
    phone?: string;
    address?: string
}تفاوت RequiredUserType و UserInterface در این هست که پراپرتی های اون به حالت اجباری در اومدهتفاوت PartialUserType و UserInterface در این هست که پراپرتی های اون به حالت اختیاری در اومدهتفاوت PickUserType و UserInterface در این هست که فقط شامل email و phone هستتفاوت OmitUserType و UserInterface در این هست که شامل پراپرتی های firstName و lastName نیستخب حالا بریم سر اصل مطلبهمونطور که میبنید در UserInterface پراپرتی های lastName و phone و address  اختیاری و email و firstName و age اجباری هستند. حالا چند تا نیازمندی مطرح می‌کنم و میریم ببینیم چجوری می‌شه بهشون پاسخ داد.نبازمندی ۱:  تایپی داشته باشیم که فقط پراپرتی های email و lastName اجباری و بقیه اختیاری باشهنبازمندی ۲:  تایپی داشته باشیم که فقط پراپرتی های lastName و age اختیاری و بقیه اجباری باشهنیازمندی ۳:  تایپی داشته باشیم که علاوه بر پراپرتی هایی که هم اکنون اختیاری هستند (lastName و phone و address )، پراپرتی age هم اختیاری بشه و بقیه بدون تغییرنیازمندی ۴:  تایپی داشته باشیم که علاوه بر پراپرتی هایی که هم اکنون اجباری هستند (email و firstName و age )، پراپرتی phone هم اجباری بشه و بقیه بدون تغییرپاسخ نیازمندی ۱type SomeRequired&lt;T, P extends keyof T&gt; = Required&lt;Pick&lt;T, P&gt;&gt; &amp; Partial&lt;Omit&lt;T, P&gt;&gt;
type Ans1 = SomeRequired&lt;UserInterface, &#039;email&#039; | &#039;lastName&#039;&gt;به عنوان ورودی تایپ T و یونیونی از پراپرتی هاش گرفته می شه، در سمت چپ اپراتور &amp; پراپرتی های پاس داده شده از تایپ T انتخاب شده و به حالت Required درمیان. در سمت راست &amp; پراپرتی های پاس داده شده از تایپ T حذف شده و بقیه پراپرتی ها به حالت Partial در میان. این ۲ تایپ با هم combine میشوند (عملگر &amp;) و تایپ مورد نظر ما بوجود میاد  مراحلی که قدم به قدم اتفاق میفته:Required&lt;Pick&lt;UserInterface, &#039;email&#039; | &#039;lastName&#039;&gt;&gt; &amp; Partial&lt;Omit&lt;UserInterface, &#039;email&#039; | &#039;lastName&#039;&gt;&gt;

// =&gt; 

Required&lt;{email: string; lastName?: string}&gt; &amp; Partial&lt;{firstName: string; age: number; phone?: string; address?: string}&gt;

// =&gt;

{
  email: string; 
  lastName: string
} &amp; {
  firstName?: string;
  age?: number;
  phone?: string;
  address?: string
}

// =&gt;

{
  email: string;  
  lastName: string
  firstName?: string; 
  age?: number; 
  phone?: string;
  address?: string
}پاسخ نیازمندی ۲type SomePartial&lt;T, P extends keyof T&gt; = Required&lt;Omit&lt;T, P&gt;&gt; &amp; Partial&lt;Pick&lt;T, P&gt;&gt;
type Ans2 = SomePartial&lt;UserInterface, &#039;lastName&#039; | &#039;age&#039;&gt;به عنوان ورودی تایپ T و یونیونی از پراپرتی هاش گرفته می شه، در سمت چپ اپراتور &amp; پراپرتی های پاس داده شده از تایپ T حذف شده و به حالت Required درمیان. در سمت راست &amp; پراپرتی های پاس داده شده از تایپ T انتخاب شده و به حالت Partial در میان. این ۲ تایپ با هم combine میشن (عملگر &amp;) و تایپ مورد نظر ما بوجود میاد.مراحلی که اتفاق میفته:Required&lt;Omit&lt;UserInterface, &#039;lastName&#039; | &#039;age&#039;&gt;&gt; &amp; Partial&lt;Pick&lt;UserInterface, &#039;lastName&#039; | &#039;age&#039;&gt;&gt;

// =&gt; 

Required&lt;{email: string; firstName: string; phone?: string; address?: string}&gt; &amp; Partial&lt;{lastName: string; age: number;}&gt;

// =&gt;

{
  email: string; 
  firstName: string;
  phone: string;
  address: string
} &amp; {
  lastName?: string;
  age?: number;
}

// =&gt;

{
  email: string; 
  firstName: string;
  lastName?: string
  age?: number; 
  phone: string;
  address: string
}پاسخ نیازمندی ۳type AddPartial&lt;T, P extends keyof T&gt; = Omit&lt;T, P&gt; &amp; Partial&lt;Pick&lt;T, P&gt;&gt;
type Ans3 = AddPartial&lt;UserInterface, &#039;age&#039;&gt;به عنوان ورودی تایپ T و یونیونی از پراپرتی هاش گرفته می شه، در سمت چپ اپراتور &amp; پراپرتی های پاس داده شده از تایپ T حذف میشن. در سمت راست &amp; پراپرتی های پاس داده شده از تایپ T انتخاب شده و به حالت Partial در میان. این ۲ تایپ با هم combine میشن (عملگر &amp;) و تایپ مورد نظر ما بوجود میاد.مراحلی که اتفاق میفته:Omit&lt;UserInterface, &#039;age&#039;&gt; &amp; Partial&lt;Pick&lt;UserInterface, &#039;age&#039;&gt;&gt;

// =&gt; 

{ email: string; firstName: string; lastName?: string; phone?: string; address?: string} &amp; Partial&lt;{age: number}&gt;

// =&gt;

{
  email: string;
  firstName: string;
  lastName?: string;
  phone?: string;
  address?: string
} &amp; {
  age?: number;
}

// =&gt;

{
  email: string; 
  firstName: string;
  lastName?: string
  age?: number; 
  phone?: string;
  address?: string
}پاسخ نیازمندی ۴type AddRequired&lt;T, P extends keyof T&gt; = Omit&lt;T, P&gt; &amp; Required&lt;Pick&lt;T, P&gt;&gt;
type Ans4 = AddRequired&lt;UserInterface, &#039;phone&#039;&gt;به عنوان ورودی تایپ T و یونیونی از پراپرتی هاش گرفته می شه، در سمت چپ اپراتور &amp; پراپرتی های پاس داده شده از تایپ T حذف میشن. در سمت راست &amp; پراپرتی های پاس داده شده از تایپ T انتخاب شده و به حالت Required در میان. این ۲ تایپ با هم combine میشن (عملگر &amp;) و تایپ مورد نظر ما بوجود میاد.مراحلی که اتفاق میفته:Omit&lt;UserInterface, &#039;phone&#039;&gt; &amp; Required&lt;Pick&lt;UserInterface, &#039;phone&#039;&gt;&gt;

// =&gt; 

{ email: string; firstName: string; lastName?: string; age: number; address?: string} &amp; Required&lt;{phone?: number}&gt;

// =&gt;

{ email: string; firstName: string; lastName?: string; age: number; address?: string} &amp; {phone: number}

// =&gt;

{
  email: string;
  firstName: string;
  lastName?: string;
  age: number;
  phone: string;
  address?: string
}امیدوارم خیلی بد توضیح نداده باشم که هیچکی هیچی نفهمه :)اگه خطایی تو این محتوا دیدین خوشحال میشم که تو کامنت ها بهم تذکر بدین. خیلی ممنون از وقتی که برای مطالعه گذاشتید.</description>
                <category>رضا میرزاپور</category>
                <author>رضا میرزاپور</author>
                <pubDate>Fri, 07 Jan 2022 00:55:25 +0330</pubDate>
            </item>
            </channel>
</rss>