TypeScript

الأنواع المتقدمة في TypeScript — دليل شامل 2026

📅 2026-10-07⏱ 9 دقائق قراءة
في المقال السابق، تعلمت الأدوية (Generics) وكيف تكتب كوداً مرناً وآمناً. الآن سنصل إلى المستوى المتقدم في TypeScript — **الأنواع المتقدمة** التي تمنحك قوة هائلة في التحكم بأنواع البيانات. في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم Union, Intersection, Conditional, Mapped, و Template Literal Types، مع تمارين وحلول. ## Union Types — أنواع الاتحاد Union تسمح لمتغير بأن يكون **أحد عدة أنواع**. ```typescript type Status = "pending" | "approved" | "rejected"; type ID = string | number; let userId: ID = "ABC123"; // ✅ userId = 12345; // ✅ // userId = true; // ❌ خطأ ``` **مثال عملي: دالة تطبع ID** ```typescript function printId(id: string | number): void { if (typeof id === "string") { console.log("نصي:", id.toUpperCase()); } else { console.log("رقمي:", id); } } printId("ABC"); // نصي: ABC printId(123); // رقمي: 123 ``` ## Intersection Types — أنواع التقاطع Intersection تدمج عدة أنواع في نوع واحد. ```typescript type Person = { name: string; age: number; }; type Employee = { company: string; salary: number; }; type EmployeePerson = Person & Employee; const emp: EmployeePerson = { name: "أحمد", age: 25, company: "Google", salary: 50000, }; ``` **الفرق بين Union و Intersection:** | Union (`|`) | Intersection (`&`) | |-------------|---------------------| | "أو" | "و" | | أحد الأنواع | كل الأنواع معاً | | `string \| number` | `A & B` | ## Type Guards — حراس النوع Type Guards هي طرق لتحقق TypeScript من نوع المتغير. ### 1. `typeof` ```typescript function process(value: string | number): void { if (typeof value === "string") { console.log(value.toUpperCase()); } else { console.log(value.toFixed(2)); } } ``` ### 2. `instanceof` ```typescript class Dog { bark() { console.log("هاو هاو!"); } } class Cat { meow() { console.log("مياو!"); } } function makeSound(animal: Dog | Cat): void { if (animal instanceof Dog) { animal.bark(); } else { animal.meow(); } } ``` ### 3. `in` operator ```typescript type Fish = { swim: () => void }; type Bird = { fly: () => void }; function move(animal: Fish | Bird): void { if ("swim" in animal) { animal.swim(); } else { animal.fly(); } } ``` ### 4. Type Predicates — دوال التحقق ```typescript interface User { name: string; email: string; } function isUser(value: unknown): value is User { return ( typeof value === "object" && value !== null && "name" in value && "email" in value ); } const data: unknown = { name: "أحمد", email: "ahmed@example.com" }; if (isUser(data)) { console.log(data.name); // ✅ TypeScript تعرف أن data هي User } ``` ## Conditional Types — الأنواع الشرطية Conditional Types تختار نوعاً بناءً على شرط. ```typescript type IsString<T> = T extends string ? "yes" : "no"; type A = IsString<string>; // "yes" type B = IsString<number>; // "no" type C = IsString<boolean>; // "no" ``` **مثال عملي: Flatten** ```typescript type Flatten<T> = T extends Array<infer U> ? U : T; type A = Flatten<string[]>; // string type B = Flatten<number>; // number type C = Flatten<boolean[]>; // boolean ``` **`infer`:** كلمة مفتاحية تستنتج النوع. ## Mapped Types — الأنواع المعيّنة Mapped Types تحوّل كل خصائص نوع إلى نوع آخر. ```typescript type User = { id: number; name: string; email: string; }; type ReadonlyUser = { readonly [K in keyof User]: User[K]; }; type OptionalUser = { [K in keyof User]?: User[K]; }; ``` **Utility Types الشائعة:** ```typescript type PartialUser = Partial<User>; // كل الخصائص اختيارية type RequiredUser = Required<User>; // كل الخصائص مطلوبة type ReadonlyUser = Readonly<User>; // كل الخصائص للقراءة type PickedUser = Pick<User, "id" | "name">; // خصائص محددة type OmittedUser = Omit<User, "email">; // حذف خصائص ``` ## Template Literal Types — أنواع القوالب النصية ```typescript type Greeting = `مرحباً ${string}`; const greeting1: Greeting = "مرحباً أحمد"; // ✅ const greeting2: Greeting = "مرحباً محمد"; // ✅ // const greeting3: Greeting = "أهلاً"; // ❌ ``` **مثال عملي: أنواع الأحداث** ```typescript type EventName = "click" | "focus" | "blur"; type EventHandler = `on${Capitalize<EventName>}`; // النتيجة: "onClick" | "onFocus" | "onBlur" const handler: EventHandler = "onClick"; ``` **مثال متقدم: CSS Properties** ```typescript type CSSUnit = "px" | "rem" | "em" | "%"; type CSSValue = `${number}${CSSUnit}` | number; const width1: CSSValue = "100px"; // ✅ const width2: CSSValue = "2rem"; // ✅ const width3: CSSValue = 100; // ✅ // const width4: CSSValue = "100"; // ❌ ``` ## Utility Types المتقدمة ### 1. `Exclude<T, U>` ```typescript type T = Exclude<"a" | "b" | "c", "a">; // النتيجة: "b" | "c" ``` ### 2. `Extract<T, U>` ```typescript type T = Extract<"a" | "b" | "c", "a" | "f">; // النتيجة: "a" ``` ### 3. `NonNullable<T>` ```typescript type T = NonNullable<string | null | undefined>; // النتيجة: string ``` ### 4. `ReturnType<T>` ```typescript function getUser() { return { id: 1, name: "أحمد" }; } type User = ReturnType<typeof getUser>; // النتيجة: { id: number; name: string } ``` ### 5. `Parameters<T>` ```typescript function greet(name: string, age: number): void {} type Params = Parameters<typeof greet>; // النتيجة: [name: string, age: number] ``` ### 6. `Awaited<T>` ```typescript type T = Awaited<Promise<string>>; // النتيجة: string async function fetchData(): Promise<{ id: number }> { return { id: 1 }; } type Data = Awaited<ReturnType<typeof fetchData>>; // النتيجة: { id: number } ``` ## Discriminated Unions — الاتحادات المميزة نمط قوي لتمثيل حالات متعددة. ```typescript type LoadingState = { status: "loading"; }; type SuccessState = { status: "success"; data: string[]; }; type ErrorState = { status: "error"; message: string; }; type State = LoadingState | SuccessState | ErrorState; function render(state: State): void { switch (state.status) { case "loading": console.log("جاري التحميل..."); break; case "success": console.log("البيانات:", state.data); break; case "error": console.log("خطأ:", state.message); break; } } ``` **الفائدة:** TypeScript تعرف **بالضبط** الخصائص المتاحة في كل حالة. ## تمارين عملية ### تمرين 1: Union Types عرّف نوعاً يقبل `string | number | boolean`. **الحل:** ```typescript type Value = string | number | boolean; function printValue(value: Value): void { console.log(value); } printValue("أحمد"); printValue(25); printValue(true); ``` ### تمرين 2: Intersection ادمج نوعين في نوع واحد. **الحل:** ```typescript type A = { a: string }; type B = { b: number }; type AB = A & B; const obj: AB = { a: "أحمد", b: 25 }; ``` ### تمرين 3: Type Guard اكتب دالة `typeof` للتمييز بين string و number. **الحل:** ```typescript function process(value: string | number): string { if (typeof value === "string") { return value.toUpperCase(); } return value.toFixed(2); } console.log(process("أحمد")); // أحمد console.log(process(25.5)); // 25.50 ``` ### تمرين 4: Conditional Type اكتب `IsArray<T>` يتحقق إذا كان النوع مصفوفة. **الحل:** ```typescript type IsArray<T> = T extends any[] ? true : false; type A = IsArray<string[]>; // true type B = IsArray<number>; // false ``` ### تمرين 5: Mapped Type أنشئ نوعاً `Nullable<T>` يجعل كل الخصائص قابلة لـ null. **الحل:** ```typescript type Nullable<T> = { [K in keyof T]: T[K] | null; }; type User = { id: number; name: string }; type NullableUser = Nullable<User>; // { id: number | null; name: string | null } ``` ### تمرين 6: Template Literal Type عرّف نوعاً للألوان بصيغة hex. **الحل:** ```typescript type HexColor = `#${string}`; const red: HexColor = "#FF0000"; const green: HexColor = "#00FF00"; // const blue: HexColor = "blue"; // ❌ ``` ### تمرين 7: Exclude/Extract استخدم `Exclude` و `Extract`. **الحل:** ```typescript type Colors = "red" | "green" | "blue" | "yellow"; type Primary = Exclude<Colors, "yellow">; // "red" | "green" | "blue" type Warm = Extract<Colors, "red" | "yellow">; // "red" | "yellow" ``` ### تمرين 8: Discriminated Union أنشئ نوعاً يمثل حالة API. **الحل:** ```typescript type ApiState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: string } | { status: "error"; error: string }; function handleState(state: ApiState): void { switch (state.status) { case "idle": console.log("في الانتظار"); break; case "loading": console.log("جاري التحميل"); break; case "success": console.log("البيانات:", state.data); break; case "error": console.log("خطأ:", state.error); break; } } ``` ## حل المشاكل الشائعة ### 🔴 المشكلة 1: `Property 'X' does not exist on type 'Y'` **السبب:** الوصول لخاصية غير موجودة في Union. ```typescript function process(value: string | number) { console.log(value.length); // ❌ number ليس له length } ``` **الحل:** استخدم Type Guard: ```typescript function process(value: string | number) { if (typeof value === "string") { console.log(value.length); } } ``` ### 🔴 المشكلة 2: `Type instantiation is excessively deep` **السبب:** نوع معقد جداً. **الحل:** قسّم النوع إلى أجزاء أصغر. ### 🔴 المشكلة 3: `Type 'X' is not assignable to type 'Y'` **السبب:** النوع المستنتج مختلف. **الحل:** استخدم `as` (بحذر) أو عدّل النوع. ## جدول الأنواع المتقدمة <table> <thead> <tr> <th>النوع</th> <th>الوصف</th> <th>مثال</th> </tr> </thead> <tbody> <tr> <td><code>Union</code></td> <td>أو</td> <td><code>string | number</code></td> </tr> <tr> <td><code>Intersection</code></td> <td>و</td> <td><code>A &amp; B</code></td> </tr> <tr> <td><code>Type Guard</code></td> <td>تحقق من النوع</td> <td><code>typeof x === "string"</code></td> </tr> <tr> <td><code>Conditional</code></td> <td>شرطي</td> <td><code>T extends U ? X : Y</code></td> </tr> <tr> <td><code>Mapped</code></td> <td>تحويل الخصائص</td> <td><code>[K in keyof T]</code></td> </tr> <tr> <td><code>Template Literal</code></td> <td>قوالب نصية</td> <td><code>`on${Event}`</code></td> </tr> <tr> <td><code>Exclude</code></td> <td>استبعاد</td> <td><code>Exclude&lt;T, U&gt;</code></td> </tr> <tr> <td><code>Extract</code></td> <td>استخراج</td> <td><code>Extract&lt;T, U&gt;</code></td> </tr> <tr> <td><code>ReturnType</code></td> <td>نوع الإرجاع</td> <td><code>ReturnType&lt;F&gt;</code></td> </tr> <tr> <td><code>Discriminated Union</code></td> <td>اتحاد مميز</td> <td><code>{ status: "..." }</code></td> </tr> </tbody> </table> ## قائمة تحقق نهائية <table> <thead> <tr> <th>المهمة</th> <th>الحالة</th> </tr> </thead> <tbody> <tr> <td>فهم Union و Intersection</td> <td>⬜</td> </tr> <tr> <td>استخدام Type Guards</td> <td>⬜</td> </tr> <tr> <td>Conditional Types</td> <td>⬜</td> </tr> <tr> <td>Mapped Types</td> <td>⬜</td> </tr> <tr> <td>Template Literal Types</td> <td>⬜</td> </tr> <tr> <td>Utility Types المتقدمة</td> <td>⬜</td> </tr> <tr> <td>Discriminated Unions</td> <td>⬜</td> </tr> <tr> <td>حل التمارين الثمانية</td> <td>⬜</td> </tr> </tbody> </table> ## ماذا بعد هذا المقال؟ الآن بعد أن أتقنت الأنواع المتقدمة، أنت جاهز للمقال التالي: 1. **مشروع React** — تطبيق عملي. 2. **مشروع Node.js** — تطبيق عملي آخر. 3. **نصائح احترافية** — أفضل الممارسات. ## الخلاصة في هذا المقال، تعلمت: - ✅ Union Types و Intersection Types. - ✅ Type Guards (typeof, instanceof, in, Type Predicates). - ✅ Conditional Types. - ✅ Mapped Types. - ✅ Template Literal Types. - ✅ Utility Types المتقدمة. - ✅ Discriminated Unions. **تذكر:** الأنواع المتقدمة هي ما يميز المطورين المحترفين. أتقنها جيداً، وستتمكن من كتابة أنواع معقدة ودقيقة. **هل أتقنت الأنواع المتقدمة؟ شاركنا في التعليقات!**