الأنواع المتقدمة في TypeScript — دليل شامل 2026
دليل عملي مفصل للأنواع المتقدمة في TypeScript — Union, Intersection, Conditional, Mapped, Template Literal، مع تمارين وحلول
في المقال السابق، تعلمت الأدوية (Generics) وكيف تكتب كوداً مرناً وآمناً. الآن سنصل إلى المستوى المتقدم في TypeScript — الأنواع المتقدمة التي تمنحك قوة هائلة في التحكم بأنواع البيانات.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم Union, Intersection, Conditional, Mapped, و Template Literal Types، مع تمارين وحلول.
Union Types — أنواع الاتحاد
Union تسمح لمتغير بأن يكون أحد عدة أنواع.
type Status = "pending" | "approved" | "rejected";
type ID = string | number;
let userId: ID = "ABC123"; // ✅
userId = 12345; // ✅
// userId = true; // ❌ خطأ
مثال عملي: دالة تطبع ID
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 تدمج عدة أنواع في نوع واحد.
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
function process(value: string | number): void {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
2. instanceof
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
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 — دوال التحقق
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: "[email protected]" };
if (isUser(data)) {
console.log(data.name); // ✅ TypeScript تعرف أن data هي User
}
Conditional Types — الأنواع الشرطية
Conditional Types تختار نوعاً بناءً على شرط.
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
type C = IsString<boolean>; // "no"
مثال عملي: Flatten
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 تحوّل كل خصائص نوع إلى نوع آخر.
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 الشائعة:
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 — أنواع القوالب النصية
type Greeting = `مرحباً ${string}`;
const greeting1: Greeting = "مرحباً أحمد"; // ✅
const greeting2: Greeting = "مرحباً محمد"; // ✅
// const greeting3: Greeting = "أهلاً"; // ❌
مثال عملي: أنواع الأحداث
type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// النتيجة: "onClick" | "onFocus" | "onBlur"
const handler: EventHandler = "onClick";
مثال متقدم: CSS Properties
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>
type T = Exclude<"a" | "b" | "c", "a">;
// النتيجة: "b" | "c"
2. Extract<T, U>
type T = Extract<"a" | "b" | "c", "a" | "f">;
// النتيجة: "a"
3. NonNullable<T>
type T = NonNullable<string | null | undefined>;
// النتيجة: string
4. ReturnType<T>
function getUser() {
return { id: 1, name: "أحمد" };
}
type User = ReturnType<typeof getUser>;
// النتيجة: { id: number; name: string }
5. Parameters<T>
function greet(name: string, age: number): void {}
type Params = Parameters<typeof greet>;
// النتيجة: [name: string, age: number]
6. Awaited<T>
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 — الاتحادات المميزة
نمط قوي لتمثيل حالات متعددة.
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.
الحل:
type Value = string | number | boolean;
function printValue(value: Value): void {
console.log(value);
}
printValue("أحمد");
printValue(25);
printValue(true);
تمرين 2: Intersection
ادمج نوعين في نوع واحد.
الحل:
type A = { a: string };
type B = { b: number };
type AB = A & B;
const obj: AB = { a: "أحمد", b: 25 };
تمرين 3: Type Guard
اكتب دالة typeof للتمييز بين string و number.
الحل:
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> يتحقق إذا كان النوع مصفوفة.
الحل:
type IsArray<T> = T extends any[] ? true : false;
type A = IsArray<string[]>; // true
type B = IsArray<number>; // false
تمرين 5: Mapped Type
أنشئ نوعاً Nullable<T> يجعل كل الخصائص قابلة لـ null.
الحل:
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.
الحل:
type HexColor = `#${string}`;
const red: HexColor = "#FF0000";
const green: HexColor = "#00FF00";
// const blue: HexColor = "blue"; // ❌
تمرين 7: Exclude/Extract
استخدم Exclude و Extract.
الحل:
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.
الحل:
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.
function process(value: string | number) {
console.log(value.length); // ❌ number ليس له length
}
الحل: استخدم Type Guard:
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 (بحذر) أو عدّل النوع.
جدول الأنواع المتقدمة
| النوع | الوصف | مثال |
|---|---|---|
Union | أو | string | number |
Intersection | و | A & B |
Type Guard | تحقق من النوع | typeof x === "string" |
Conditional | شرطي | T extends U ? X : Y |
Mapped | تحويل الخصائص | [K in keyof T] |
Template Literal | قوالب نصية | `on${Event}` |
Exclude | استبعاد | Exclude<T, U> |
Extract | استخراج | Extract<T, U> |
ReturnType | نوع الإرجاع | ReturnType<F> |
Discriminated Union | اتحاد مميز | { status: "..." } |
قائمة تحقق نهائية
| المهمة | الحالة |
|---|---|
| فهم Union و Intersection | ⬜ |
| استخدام Type Guards | ⬜ |
| Conditional Types | ⬜ |
| Mapped Types | ⬜ |
| Template Literal Types | ⬜ |
| Utility Types المتقدمة | ⬜ |
| Discriminated Unions | ⬜ |
| حل التمارين الثمانية | ⬜ |
ماذا بعد هذا المقال؟
الآن بعد أن أتقنت الأنواع المتقدمة، أنت جاهز للمقال التالي:
- مشروع React — تطبيق عملي.
- مشروع Node.js — تطبيق عملي آخر.
- نصائح احترافية — أفضل الممارسات.
الخلاصة
في هذا المقال، تعلمت:
- ✅ Union Types و Intersection Types.
- ✅ Type Guards (typeof, instanceof, in, Type Predicates).
- ✅ Conditional Types.
- ✅ Mapped Types.
- ✅ Template Literal Types.
- ✅ Utility Types المتقدمة.
- ✅ Discriminated Unions.
تذكر: الأنواع المتقدمة هي ما يميز المطورين المحترفين. أتقنها جيداً، وستتمكن من كتابة أنواع معقدة ودقيقة.
هل أتقنت الأنواع المتقدمة؟ شاركنا في التعليقات!
الأدوية (Generics) في TypeScript — دليل شامل 2026
مشروع React مع TypeScript — تطبيق مهام كامل 2026
📚 مقالات ذات صلة
مشروع Node.js مع TypeScript — API كامل 2026
مشروع عملي لبناء API كامل بـ Node.js و Express و TypeScript — خطوة بخطوة مع الكود الكامل والشرح
مشروع React مع TypeScript — تطبيق مهام كامل 2026
مشروع عملي لبناء تطبيق مهام (Todo App) بـ React و TypeScript — خطوة بخطوة مع الكود الكامل والشرح
الأدوية (Generics) في TypeScript — دليل شامل 2026
دليل عملي مفصل للأدوية في TypeScript — الدوال العامة، الواجهات العامة، القيود، مع تمارين وحلول