كيف تجتاز مقابلة TypeScript: أفضل أسئلة المستوى المتقدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كيف تجتاز مقابلة TypeScript: أفضل أسئلة المستوى المتقدم

\n\n

نادراً ما تخلو مقابلة التقديم لوظيفة مطور واجهات أمامية أول (Senior Frontend) أو مطور كامل (Fullstack) من أسئلة عميقة حول TypeScript. إذا كنت تعرف الأنواع والواجهات الأساسية عن ظهر قلب، فلكي تجتاز المقابلة الفنية للحصول على درجة عالية، يجب أن تكون على دراية بنظام الأنواع المتقدم. في هذه المقالة، قمنا بتجميع أفضل 5 أسئلة ومهام يتم طرحها غالباً في مقابلات TypeScript للمستوى المتقدم. كل نقطة مصحوبة بتحليل وأمثلة كود.

\n\n

1. الأنواع الشرطية (Conditional Types) والكلمة المفتاحية infer

\n\n

تسمح الأنواع الشرطية بإنشاء أنواع تعتمد على شرط. بالاقتران مع infer، يمكنك "استخراج" أجزاء من الأنواع، كما هو الحال في مطابقة الأنماط (Pattern Matching).

\n\n

السؤال: اكتب نوع ReturnType (بدون استخدام النوع المدمج).

\n\n

التحليل: نستخدم نوعاً شرطياً مع infer لالتقاط القيمة المرجعة للدالة.

\n\n
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\n\n// مثال على الاستخدام\nfunction greet(name: string): string {\n  return `Hello, ${name}`;\n}\n\ntype GreetReturn = MyReturnType<typeof greet>; // string
\n\n

كيف تجيب في المقابلة: اشرح أن infer R ينشئ متغير نوع جديد R يلتقط النوع المرتجع من توقيع الدالة. إذا لم يتحقق الشرط (تم تمرير شيء ليس دالة)، يصبح النوع never.

\n\n

2. الأنواع المعينة (Mapped Types) والمعدلات (Modifiers)

\n\n

تسمح الأنواع المعينة بإنشاء أنواع جديدة عن طريق تحويل خصائص نوع موجود. المستوى المتقدم يتضمن العمل مع المعدلات +، -، as والمفاتيح عبر keyof.

\n\n

السؤال: أنشئ نوع DeepReadonly الذي يجعل جميع خصائص الكائن (بما في ذلك الخصائص المتداخلة) للقراءة فقط (readonly).

\n\n
type DeepReadonly<T> = {\n  readonly [K in keyof T]: T[K] extends Record<string, unknown> \n    ? DeepReadonly<T[K]> \n    : T[K];\n};\n\ninterface User {\n  name: string;\n  address: {\n    city: string;\n    zip: number;\n  };\n}\n\ntype ReadonlyUser = DeepReadonly<User>;\n// جميع الخصائص أصبحت للقراءة فقط، بما في ذلك address.city
\n\n

كيف تجيب: أظهر الاستدعاء التكراري لـ DeepReadonly للكائنات المتداخلة. اشرح كيف يتم استخدام Record<string, unknown> للتحقق مما إذا كانت القيمة كائناً.

\n\n

3. أنواع القوالب النصية (Template Literal Types)

\n\n

تسمح أنواع القوالب النصية بمعالجة أنواع السلاسل النصية على مستوى التجميع. هذه أداة قوية لإنشاء واجهات برمجة تطبيقات (APIs) صارمة.

\n\n

السؤال: قم بتنفيذ نوع EventName الذي يأخذ سلسلة نصية ويعيد النوع "on{سلسلة}" مع Capitalize الصحيح.

\n\n
type EventName<T extends string> = `on${Capitalize<T>}`;\n\ntype ClickEvent = EventName<'click'>; // "onClick"\ntype FocusEvent = EventName<'focus'>; // "onFocus"\n\n// مثال متقدم: الاستخراج من سلسلة نصية\ntype ExtractAction<T extends string> = \n  T extends `on${infer Action}` ? Uncapitalize<Action> : never;\n\ntype Action = ExtractAction<'onSubmit'>; // "submit"
\n\n

كيف تجيب: لاحظ الأنواع المدمجة Capitalize و Uncapitalize. أظهر كيف يعمل infer داخل القوالب النصية لتحليل السلاسل النصية.

\n\n

4. الأجناس (Generics) مع القيود وأنواع الصفوف المتغيرة (Variadic Tuple Types)

\n\n

أنواع الصفوف المتغيرة (ظهرت في TS 4.0) تسمح بالعمل مع صفوف (tuples) ذات طول عشوائي. هذا لا غنى عنه عند إنشاء دوال آمنة من حيث النوع مع عدد متغير من الوسائط.

\n\n

السؤال: اكتب نوعاً لدالة

المدونات

توصيات الكتب