0Pricing
TypeScript Academy · درس

تجنّب عمليات الأنواع المكلفة

حدّدوا الأنواع التكرارية بعمق أو التوزيعية وأصلحوها

تجنّب عمليات الأنواع المكلفة درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ما الذي يجعل عملية الأنواع مكلفة؟

تجبر الأنواع العودية بعمق، وتوزيعات الاتحادات الكبيرة، وسلاسل infer المعقدة TypeScript على إنشاء العديد من متغيرات الأنواع، مما يسبب تباطؤًا أُسّيًا.

// Expensive: distributes over every member of a large union
type FilterStrings<T> = T extends string ? T : never;
type Result = FilterStrings<string | number | boolean | null | undefined | ...>;

تجنّب أحجام الاتحادات المفرطة

يمكن للاتحادات التي تضم مئات الأعضاء، مثل تلك الناتجة عن العديد من القيم النصية الحرفية، أن تجعل فحص الأنواع بطيئًا جدًا. فكّروا في تضييق النطاق أو استخدام string مع إجراء التحقق.

// Expensive
type HugeUnion = "a" | "b" | "c" | /* 200 more ... */ "z";
// Better: string with a runtime check
function isValid(s: string): s is ValidString { return VALID_SET.has(s); }

فضّلوا الواجهات على الأسماء المستعارة المعقدة للأنواع

تخزّن TypeScript الواجهات مؤقتًا بدرجة أكبر من تقاطعات الأسماء المستعارة المعقدة للأنواع. فضّلوا interface لأشكال الكائنات التي يُشار إليها مرات كثيرة.

// Slow: recomputed union intersection each time
type BigObject = TypeA & TypeB & TypeC & TypeD;
// Fast: interface (cached)
interface BigObject extends TypeA, TypeB, TypeC, TypeD {}

حدّدوا عمق العودية

الأنواع الشرطية العودية قوية، لكنها قد تتجاوز حد العمق في TypeScript، الذي يبلغ عادةً 100 مستوى. أضيفوا عدّادًا للعمق للتوقف مبكرًا.

type Flatten<T, Depth extends number[] = []> =
  Depth["length"] extends 10 ? T
  : T extends (infer U)[] ? Flatten<U, [...Depth, 0]>
  : T;

خزّنوا الأنواع الوسيطة مؤقتًا

سمّوا الأنواع الوسيطة المعقدة حتى تتمكن TypeScript من تخزينها مؤقتًا وإعادة استخدامها بدلًا من إعادة حسابها عند كل مرجع.

// Before: recomputed at each use
type MyResult<T> = T extends SomeComplex<infer U> ? Transform<U> : never;

// After: split into named intermediates
type ExtractU<T> = T extends SomeComplex<infer U> ? U : never;
type MyResult<T> = Transform<ExtractU<T>>;

تجنّبوا الأنواع المعيّنة العميقة على الكائنات الكبيرة

يؤدي تطبيق DeepReadonly على نوع كائن كبير جدًا إلى جعل TypeScript تتصفح كل خاصية بشكل عودي، وهذا مكلف.

// Expensive on 50-property nested objects
type Safe = DeepReadonly<HugeConfig>;
// Better: annotate at creation time with const assertions

استخدموا التقييم الكسول للأنواع العامة

يؤدي تغليف نوع مكلف داخل thunk، أي نوع دالة يعيد ذلك النوع، إلى تأجيل التقييم حتى تصبح الحاجة إلى النوع فعلية.

// Lazy evaluation via wrapper
type Lazy<T> = () => T;
type ExpensiveLazy = Lazy<DeepReadonly<HugeConfig>>;

فضّلوا أنواع الإرجاع الصريحة

تمنع كتابة أنواع إرجاع الدوال صراحةً TypeScript من استنتاجها بشكل متكرر عند كل موضع استدعاء، مما يسرّع فحص الأنواع.

// Let TypeScript infer (may be slow for complex functions)
function process(data: Input) { return transform(data); }

// Faster: explicit annotation
function process(data: Input): Output { return transform(data); }

isolatedDeclarations للفحص المتوازي

يتطلب isolatedDeclarations في TypeScript 5.5+ كتابة أنواع الإرجاع صراحةً، مما يتيح فحص الأنواع بالتوازي للملفات المستقلة دون استنتاج كامل.

// tsconfig.json
{
  "compilerOptions": {
    "isolatedDeclarations": true
  }
}

مراجع المشاريع للعزل

تمنع مراجع المشاريع TypeScript من فحص الأنواع للحزم التي لم تتغير، وهذا أكبر مكسب في مستودعات monorepo الكبيرة.

# With project references:
# tsc --build only recompiles packages whose sources changed
# Unchanged packages: declaration files used directly

مراجعة: تجنّب الأنواع المكلفة

للحفاظ على سرعة TypeScript: تجنّبوا الاتحادات الضخمة، وخزّنوا الأنواع الوسيطة مؤقتًا، وفضّلوا الواجهات على الأسماء المستعارة المعقدة، وحدّدوا عمق العودية، واستخدموا أنواع الإرجاع الصريحة، واعزلوا الحزم باستخدام مراجع المشاريع.

تحقّق سريع

ما الأسلوب الذي يساعد TypeScript على تخزين شكل كائن مؤقتًا بدرجة أكبر؟

ما تعلّمتموه

تشمل عمليات أنواع TypeScript المكلفة الاتحادات الكبيرة، والعودية العميقة، والاستنتاج المعقد المتكرر. حسّنوا الأداء من خلال تخزين الأنواع الوسيطة مؤقتًا، وتفضيل الواجهات، والحد من أحجام الاتحادات، واستخدام مراجع المشاريع في مستودعات monorepo.

الأسئلة الشائعة

هل درس «تجنّب عمليات الأنواع المكلفة» مجاني؟

نعم — نص درس «تجنّب عمليات الأنواع المكلفة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «تجنّب عمليات الأنواع المكلفة»؟

حدّدوا الأنواع التكرارية بعمق أو التوزيعية وأصلحوها تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تجنّب عمليات الأنواع المكلفة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تحليل أداء تجميع TypeScript البطيء
  2. تجنّب عمليات الأنواع المكلفة
  3. ‏skipLibCheck والتصريحات المعزولة
  4. التحقق من الأنواع في CI: الاستراتيجيات والأدوات
← العودة إلى TypeScript Academy