فهرست سرفصل‌های 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 — انواع پیشرفته (Advanced Types)

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

انواع پیشرفته (Advanced Types)

در این صفحه با «انواع پیشرفته تایپ اسکریپت» آشنا می شوی. منظور از نوع پیشرفته، ابزارهای دقیق برای توصیف داده هاست. بنابراین خطاها کمتر می شوند و کدت قابل اعتمادتر می شود. مثلا مثل قانون های دقیق در دبیرستان که تکلیف همه چیز را روشن می کند.

مرور کوتاه انواع پیشرفته

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

Mapped Types (نوع های نگاشتی)

«نگاشتی» یعنی روی همه ویژگی های یک نوع، یک الگوی مشترک اعمال کنی؛ مثل برچسب زدن همه پوشه ها.

// Convert all properties to boolean
type Flags<T> = {
  [K in keyof T]: boolean;
};

interface User {
  id: number;
  name: string;
  email: string;
}

type UserFlags = Flags<User>;
// { id: boolean; name: boolean; email: boolean; }

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

Mapped Modifiers (اصلاح گرها)

با + و - می توانی readonly و ? را اضافه یا حذف کنی؛ مثل قفل زدن یا بازکردن کشوها.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type OptionalTodo = {
  [K in keyof Todo]?: Todo[K];
};

type Concrete<T> = {
  -readonly [K in keyof T]-?: T[K];
};

type ReadonlyRequired<T> = {
  +readonly [K in keyof T]-?: T[K];
};

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

Key Remapping (تغییر نام کلید)

می توانی کلیدها را با as تغییر نام دهی یا فیلتر کنی؛ مثل تغییر عنوان پوشه ها.

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type MethodsOnly<T> = {
  [K in keyof T as T[K] extends Function ? K : never]: T[K];
};

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

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

نوع شرطی یعنی انتخاب نوع بر اساس شرط؛ مثل اگر-وگرنه سر کلاس.

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

type A = IsString<string>;
type B = IsString<number>;

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

type Numbers = ArrayElement<number[]>;

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

infer (گرفتن نوعِ پنهان)

infer یعنی از داخل یک نوع، بخشی را بیرون بکشیم؛ مثل پیدا کردن الگو.

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

type FnParams<T> = T extends (...args: infer P) => any ? P : never;

type CtorParams<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

type InstanceOf<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

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

توزیع روی Union ها

گاهی شرطی ها روی اعضای Union پخش می شوند. با براکت می توانی پخش شدن را کنترل کنی.

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

type StrOrNumArr = ToArrayNonDist<string | number>;

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

type StrOrNumArr2 = ToArray<string | number>;

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

type Letters = FilterStrings<'a' | 'b' | 1 | 2 | 'c'>;

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

Template Literal Types (رشته های الگو)

با Template Literal می توانی الگوی رشته بسازی؛ مثل «قرمز-کوچک».

type Greeting = `Hello, ${string}`;

const validGreeting: Greeting = 'Hello, World!';

// const invalidGreeting: Greeting = 'Hi there!';

type Color = 'red' | 'green' | 'blue';

type Size = 'small' | 'medium' | 'large';

type Style = `${Color}-${Size}`;

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

دستکاری رشته ای

با Uppercase و Capitalize و… می توانی حروف را تغییر دهی؛ مثل تیترکردن.

type T1 = Uppercase<'hello'>;

type T2 = Lowercase<'WORLD'>;

type T3 = Capitalize<'typescript'>;

type T4 = Uncapitalize<'TypeScript'>;

type EventType = 'click' | 'change' | 'keydown';

type EventHandler = `on${Capitalize<EventType>}`;

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

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

می توانی پارامتر مسیر را استخراج کنی یا API تولید کنی؛ مثل ساخت نقشه راه.

type ExtractRouteParams<T> = T extends `${string}:${infer Param}/${infer Rest}`
  ? { [K in Param | keyof ExtractRouteParams<`${Rest}`>]: string }
  : T extends `${string}:${infer Param}`
  ? { [K in Param]: string }
  : {};

type Params = ExtractRouteParams<'/users/:userId/posts/:postId'>;

type EventMap = {
  click: { x: number; y: number };
  change: string;
  keydown: { key: string; code: number };
};

type EventHandlers = {
  [K in keyof EventMap as `on${Capitalize<K>}`]: (event: EventMap[K]) => void;
};

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

Utility Types (انواع کمکی)

انواع کمکی آماده هستند و تغییرات رایج را ساده می کنند؛ مثل ابزارهای جعبه ابزار.

interface User {
  id: number;
  name: string;
  email: string;
  createdAt: Date;
}

type PartialUser = Partial<User>;

type RequiredUser = Required<PartialUser>;

type ReadonlyUser = Readonly<User>;

type UserPreview = Pick<User, 'id' | 'name'>;

type UserWithoutEmail = Omit<User, 'email'>;

type UserId = User['id'];

type UserKeys = keyof User;

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

Utility های پیشرفته

با Exclude و Extract اتحادها را پالایش کن و نوع های سفارشی بساز.

type NonNullable<T> = T extends null | undefined ? never : T;

type Numbers = 1 | 2 | 3 | 'a' | 'b';

type JustNumbers = Exclude<Numbers, string>;

type JustStrings = Extract<Numbers, string>;

type A = { a: string; b: number; c: boolean };

type B = { a: string; b: number };

type C = Omit<A, keyof B>;

type Mutable<T> = {
  -readonly [K in keyof T]: T[K];
};

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

Recursive Types (نوع های بازگشتی)

بازگشتی یعنی نوع به خودش اشاره کند؛ مثل درخت پوشه ها در رایانه.

type BinaryTree<T> = {
  value: T;
  left?: BinaryTree<T>;
  right?: BinaryTree<T>;
};

type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };

type Comment = {
  id: number;
  content: string;
  replies: Comment[];
  createdAt: Date;
};

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

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

لیست پیوندی، درخت پوشه و ماشین حالت را می توان دقیق مدل کرد.

type LinkedList<T> = {
  value: T;
  next: LinkedList<T> | null;
};

type File = {
  type: 'file';
  name: string;
  size: number;
};

type Directory = {
  type: 'directory';
  name: string;
  children: (File | Directory)[];
};

type State = {
  value: string;
  transitions: {
    [event: string]: State;
  };
};

type RecursiveFunction<T> = (x: T | RecursiveFunction<T>) => void;

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

بهترین تمرین ها

ساده شروع کن، سپس دقیق شو. برای خوانایی کامنت بگذار. همچنین از انواع کمکی آماده استفاده کن تا چرخ را دوباره اختراع نکنی.

دام های رایج

پخش شدن شرطی روی Union ها می تواند غافلگیرکننده باشد. همچنین نوع های بسیار عمیق، کامپایل را کند می کنند. پس نوع ها را خرد کن و مستند کن.

جمع بندی سریع

  • نوع های نگاشتی، همه ویژگی ها را یک جا تغییر می دهند.
  • نوع های شرطی، انتخاب هوشمند انجام می دهند.
  • Template Literal، رشته ها را قانون مند می کند.
  • Utility Types، میانبرهای کاربردی می دهند.
  • بازگشتی ها، ساختارهای درختی را دقیق می سازند.

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