فهرست سرفصل‌های TypeScript
خانه (Home) معرفی (Introduction) شروع سریع (Get Started) انواع ساده (Simple Types) تعریف صریح و استنتاج نوع (Explicit & Inference) انواع ویژه (Special Types) آرایه ها (Arrays) تاپل ها (Tuples) انواع شیء (Object Types) شمارشی ها (Enums) نام مستعار و اینترفیس ها (Aliases & Interfaces) انواع اتحادی (Union Types) توابع (Functions) تبدیل نوع (Casting) کلاس ها (Classes) جنریک های پایه (Basic Generics) انواع کاربردی (Utility Types) کلیدواژه keyof (Keyof) Null (Null) Definitely Typed (Definitely Typed) به روزرسانی های نسخه 5 (5 Updates) پیکربندی (Configuration) با Node.js (with Node.js) با React (with React) ابزارها (Tooling) انواع پیشرفته (Advanced Types) نگهبان های نوع (Type Guards) انواع شرطی (Conditional Types) انواع نگاشتی (Mapped Types) استنتاج نوع (Type Inference) انواع لیترال (Literal Types) فضای نام (Namespaces) امضاهای ایندکس (Index Signatures) ادغام اعلان ها (Declaration Merging) برنامه نویسی ناهمگام (Async Programming) دکوراتورها (Decorators) در پروژه های JS (in JS Projects) مهاجرت (Migration) مدیریت خطا (Error Handling) بهترین شیوه ها (Best Practices) ادیتور (Editor) تمرین ها (Exercises) آزمون (Quiz) سرفصل دوره (Syllabus) برنامه مطالعه (Study Plan) گواهینامه (Certificate)
نتیجه‌ای برای جستجو یافت نشد.
TypeScript

TypeScript — انواع شرطی (Conditional Types)

آخرین بروزرسانی: 1404/08/14

انواع شرطی (Conditional Types)

«نوع شرطی (Conditional Type)» یعنی تصمیم گیری روی نوع ها. مثل if-else اما در سطحِ تایپ. بنابراین کد ایمن تر می شود و خطاها زودتر دیده می شوند. تصور کن از روی کارنامه، مسیر رشته را حدس می زنیم.

نوشتار پایه انواع شرطی

الگو این است: T extends U ? X : Y. اگر T قابل انتصاب به U باشد، X می شود؛ وگرنه Y.

type IsString<T> = T extends string ? true : false;

type Result1 = IsString<string>;
type Result2 = IsString<number>;
type Result3 = IsString<'hello'>;

let a: IsString<string>;
let b: IsString<number>;

مشاهده در ادیتور

انواع شرطی و اتحادها

روی اتحادها، شرطی ها «پخش» می شوند. یعنی برای هر عضو جدا محاسبه می شوند.

type ToArray<T> = T extends any ? T[] : never;

type StringOrNumberArray = ToArray<string | number>;

type ExtractString<T> = T extends string ? T : never;

type StringsOnly = ExtractString<string | number | boolean | 'hello'>;

مشاهده در ادیتور

استفاده از infer برای کشف نوع

infer یعنی «از داخل نوع، بخشش را بیرون بکش». مثل حدس زدن نمره هر درس از معدل.

type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;

function greet(): string {
  return 'Hello, world!';
}

function getNumber(): number {
  return 42;
}

type GreetReturnType = ReturnTypeOf<typeof greet>;
type NumberReturnType = ReturnTypeOf<typeof getNumber>;

type ElementType<T> = T extends (infer U)[] ? U : never;

type NumberArrayElement = ElementType<number[]>;
type StringArrayElement = ElementType<string[]>;

مشاهده در ادیتور

نوع های شرطیِ از پیش آماده

کتابخانه استاندارد، ابزارهای آماده دارد. سریع و مطمئن.

type OnlyStrings = Extract<string | number | boolean, string>;

type NoStrings = Exclude<string | number | boolean, string>;

type NotNull = NonNullable<string | null | undefined>;

type Params = Parameters<(a: string, b: number) => void>;

type Ret = ReturnType<() => string>;

مشاهده در ادیتور

الگوهای پیشرفته

بازکردن تو در توی Promise

گاهی Promise ها تودرتو هستند. با شرطی بازشان کن.

type UnwrapPromise<T> = T extends Promise<infer U> ? UnwrapPromise<U> : T;

type A = UnwrapPromise<Promise<string>>;
type B = UnwrapPromise<Promise<Promise<number>>>;
type C = UnwrapPromise<boolean>;

مشاهده در ادیتور

زنجیره if-else در سطح نوع

چند شرط را پشت سر هم بگذار. مثل مشاوره انتخاب رشته.

type TypeName<T> =
  T extends string ? 'string' :
  T extends number ? 'number' :
  T extends boolean ? 'boolean' :
  T extends undefined ? 'undefined' :
  T extends Function ? 'function' :
  'object';

type T0 = TypeName<string>;
type T1 = TypeName<42>;
type T2 = TypeName<true>;
type T3 = TypeName<() => void>;
type T4 = TypeName<Date[]>;

function processValue<T>(value: T): T extends string
  ? string
  : T extends number
  ? number
  : T extends boolean
  ? boolean
  : never {
  if (typeof value === 'string') {
    return value.toUpperCase() as any;
  } else if (typeof value === 'number') {
    return (value * 2) as any;
  } else if (typeof value === 'boolean') {
    return (!value) as any;
  } else {
    throw new Error('Unsupported type');
  }
}

const stringResult: string = processValue('hello');
const numberResult: number = processValue(10);
const boolResult: boolean = processValue(true);

مشاهده در ادیتور

نکته: برای تمرین عملی بیشتر، نمونه «کاربرد واقعی» را هم اجرا کن.

مشاهده در ادیتور

گام های عملی

  1. مسئله نوعی را دقیق بنویس.
  2. الگوی T extends U ? X : Y را بساز.
  3. اگر لازم شد، از infer برای استخراج نوع استفاده کن.
  4. روی اتحادها، نتیجه پخش شدن را بررسی کن.
  5. در پایان، با ابزارهای آماده مثل Extract مقایسه کن.

جمع بندی سریع

  • انواع شرطی تایپ اسکریپت، منطق if برای نوع هاست.
  • infer بخش های پنهان نوع را بیرون می کشد.
  • روی اتحادها، شرطی ها جداگانه اعمال می شوند.
  • از ابزارهای آماده برای سرعت بهره ببر.
  • پیچیدگی زیاد، سرعت کامپایل را کم می کند.

برای ادامه مسیر، صفحه انواع شرطی تایپ اسکریپت و همچنین نگهبان های نوع و انواع نگاشتی را ببین.