Typealias: ما هو، بناء الجملة والاستخدام

المؤلف: IT Sectr نُشر: 2026-06-20 وقت القراءة: 7 دق

Typealias هو إعلان في Swift ينشئ اسمًا بديلاً لنوع موجود دون تعريف نوع جديد. الاسم المستعار مكافئ تمامًا للنوع الأصلي في مرحلة الترجمة — يستبدل المترجم النوع الأصلي في كل مكان يُستخدم فيه typealias. وفقًا لدليل Swift Language Guide (2025)، يُستخدم typealias لتقصير التواقيع الطويلة، وتجريد الأنواع الداخلية عبر associatedtype في البروتوكولات وتبسيط معاملات generic المعقدة. على عكس غلاف النوع (wrapper)، لا يضيف typealias أمانًا للأنواع — إنه مجرد اسم مستعار لا يميزه نظام الأنواع.

النقاط الرئيسية

  • Typealias — اسم مستعار لنوع موجود، لا ينشئ نوعًا جديدًا؛ المترجم يستبدله بالأصلي
  • بناء الجملة: typealias NewName = ExistingType — يمكن التصريح به في أي مستوى (عام، محلي، داخل نوع)
  • Associatedtype — typealias داخل بروتوكول، يحدد نوعًا مرتبطًا يتم تحديده عند اعتماد البروتوكول
  • التواقيع العامة — typealias يختصر المعاملات الطويلة: typealias Result = Swift.Result<Data, Error>
  • أنواع closure — typealias يحسن readability: typealias Handler = (Int) -> Void

ما هو Typealias؟

Typealias هو إعلان في Swift يقدم اسمًا بديلاً لنوع موجود. بعد التصريح عن typealias، يمكن استخدام الاسم الجديد في أي مكان يُتوقع فيه النوع الأصلي — يعاملهما المترجم كمتطابقين. لا يضيف Typealias عزلًا دلاليًا: يمكن تمرير قيمة من نوع UserID (typealias لـ String) إلى دالة تنتظر String دون خطأ.

الأغراض الرئيسية لـ typealias هي تقصير الأسماء الطويلة، وتوثيق الغرض من النوع، وتجريد التنفيذ الملموس. على سبيل المثال، typealias JSON = [String: Any] يشير صراحةً إلى أن القاموس يُستخدم كهيكل JSON، و typealias Completion = (Result<Data, Error>) -> Void يحول توقيع closure معقدًا إلى نوع قابل للقراءة.

وفقًا لـ Swift.org (2025)، يُستخدم typealias على نطاق واسع في المكتبة القياسية. على سبيل المثال، String هو typealias لـ String (Array<Character> متخصص)، على الرغم من أن هذا التنفيذ مخفي في الإصدارات الحديثة من Swift. Void هو typealias للـ tuple الفارغ ()، مما يجعل تواقيع الدوال أكثر قابلية للقراءة.

استخدم typealias لتوثيق دلالات النوع، لكن تذكر: أنه لا يحمي من خلط مفاهيم مختلفة لنفس النوع الأساسي. للفصل الآمن للأنواع، استخدم الأغلفة (struct wrapper).

بناء الجملة والنطاقات

يتم التصريح عن Typealias بالكلمة المفتاحية typealias، متبوعة بالاسم الجديد، علامة يساوي، والنوع الموجود. الشكل الأساسي:

swift
typealias Name = ExistingType
typealias UserID = Int
typealias JSONDictionary = [String: Any]

يتم تحديد نطاق typealias حسب مكان التصريح:

المستوىمثالالرؤية
عامtypealias Name = Stringالوحدة بأكملها (خاضعة للتحكم في الوصول)
داخل نوعstruct User { typealias ID = Int }User.ID — يمكن الوصول إليه عبر النوع
داخل دالةfunc f() { typealias Local = Int }فقط داخل الدالة
داخل بروتوكولprotocol P { associatedtype T }يتم تحديده عند الاعتماد

Typealias داخل نوع (على سبيل المثال، User.ID) هو نمط شائع لتجميع الأسماء المستعارة ذات الصلة. هذا يحسن الفضاءات الاسمية: Order.ID و User.ID كلاهما Int، لكن يُقرآن كمفهومين مختلفين. يتم الوصول إلى typealias المتداخل عبر User.ID أو عبر تدوين النقطة إذا كان النوع معروفًا.

Typealias لأنواع closure

أحد أكثر استخدامات typealias شيوعًا هو تبسيط تواقيع closure. يمكن أن تكون أنواع closure في Swift مرهقة، خاصةً مع Optional والمعاملات العامة. Typealias يحول (Data?, Error?) -> Void إلى FetchResultHandler قابل للقراءة:

swift
typealias FetchResultHandler = (Data?, Error?) -> Void

func fetchUser(id: Int, completion: FetchResultHandler) {
    // network request
    completion(data, nil)
}

وفقًا لدليل أسلوب Ray Wenderlich، فإن typealias للـ closures يحسن readability لتواقيع الدوال، خاصةً في بروتوكولات التفويض وأنماط الاستدعاء. ومع ذلك، تجنب الإفراط في الأسماء المستعارة — إذا تم استخدام closure في مكان واحد، يمكن التصريح به inline.

تستخدم المكتبة القياسية لـ Swift هذا الأسلوب بنشاط. على سبيل المثال، DispatchQueue.WorkItem هو typealias لـ DispatchWorkItem، على الرغم من أنه يبدو من الخارج كنوع منفصل. Typealias للـ closures هو أداة readability — لا تفرط في استخدامها: 3–5 أسماء مستعارة للـ closures لكل وحدة هو حد معقول.

Typealias والمعاملات العامة

يمكن أن يتضمن Typealias معاملات عامة (generic)، مما ينشئ إصدارات متخصصة من الأنواع العامة. هذا مفيد بشكل خاص عند العمل مع Result و Publisher وأنواع عامة أخرى من المكتبة القياسية و Combine:

swift
typealias FetchResult = Result<Data, Error>
typealias AnyPublisherOfData = AnyPublisher<Data, Error>

func loadData() -> FetchResult {
    // data loading
}

يمكنك أيضًا إنشاء typealias بمعاملات عامة مخصصة يتم توجيهها إلى النوع الأصلي:

swift
typealias NetworkResult<T> = Result<T, NetworkError>

func fetchUser() -> NetworkResult<User> {
    // ...
}

قاعدة مهمة: لا يمكن لـ typealias إضافة قيود عامة جديدة (where clauses) — إنه فقط يوجه المعاملات إلى النوع الأصلي. إذا كانت هناك حاجة لقيود إضافية، قم بإنشاء struct أو class عام. وفقًا لـ Swift by Sundell (2024)، فإن typealias مع الـ generics هو طريقة مثالية لتقصير التواقيع المتكررة في المشاريع التي تستخدم Combine و Result و async/await بكثافة.

Associatedtype في البروتوكولات

Associatedtype هو typealias تم التصريح عنه داخل بروتوكول يحدد نوعًا مرتبطًا. على عكس typealias العادي، لا يرتبط associatedtype بنوع محدد في وقت التصريح — يتم تحديده بواسطة كل نوع يعتمد البروتوكول:

swift
protocol Container {
    associatedtype Item
    var count: Int { get }
    mutating func append(_ item: Item)
}

struct IntBox: Container {
    typealias Item = Int
    // implementation
}

struct StringBox: Container {
    typealias Item = String
    // implementation
}

يعطي Associatedtype للبروتوكولات مرونة الأنواع العامة دون تحديد نوع ملموس في مكان التصريح. هذا هو أساس العديد من أنماط Swift: Collection (Element)، IteratorProtocol (Element)، Identifiable (ID). يمكن للمترجم استنتاج associatedtype تلقائيًا من التنفيذ، لذلك غالبًا ما يتم حذف typealias Item = Int الصريح — يستنتج Swift Item كـ Int من معامل الدالة append.

وفقًا لـ Swift Evolution SE-0195 (2022)، تم تقديم أنواع النتائج الغامضة (some Container) للعمل مع البروتوكولات التي تحتوي على associatedtype — مما حل مشكلة PAT (البروتوكولات ذات الأنواع المرتبطة)، والتي كانت تمنع استخدام هذه البروتوكولات كأنواع متغيرات.

Typealias مقابل غلاف النوع

الفرق الرئيسي: typealias هو مجرد اسم آخر لنوع موجود، بينما الغلاف (wrapper) هو نوع جديد، معزول دلاليًا عن الأصل. إذا أعلنت typealias UserID = Int، فإن UserID و Int قابلان للتبادل — دالة تنتظر Int ستقبل UserID دون خطأ.

يتم إنشاء الغلاف عبر struct ويوفر أمانًا حقيقيًا للأنواع:

swift
struct UserID: RawRepresentable {
    let rawValue: Int
}

struct OrderID: RawRepresentable {
    let rawValue: Int
}

// Compilation error: cannot pass OrderID where UserID is expected

وفقًا لـ Point-Free (2025)، الأغلفة مفضلة عندما يتم تمثيل مفاهيم مختلفة بنفس النوع الأساسي (UserID مقابل OrderID). Typealias مبرر عندما يكون الهدف هو readability دون عزل: تقصير الأسماء الطويلة، توثيق الدلالات، تجريد التنفيذ عبر associatedtype. اختر typealias لسهولة القراءة، والغلاف لأمان الأنواع.

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

كيف يختلف typealias عن associatedtype؟

Typealias هو اسم مستعار لنوع موجود محدد. Associatedtype يتم التصريح عنه داخل بروتوكول ويتم تحديده بواسطة كل نوع يعتمد البروتوكول — أنواع مختلفة يمكنها استخدام associatedtype مختلف لنفس البروتوكول.

هل ينشئ typealias نوعًا جديدًا؟

لا، typealias هو مجرد اسم بديل. المترجم يستبدله بالنوع الأصلي في وقت الترجمة. لإنشاء نوع جديد ومعزول دلاليًا، استخدم struct wrapper أو enum مع rawValue.

هل يمكن استخدام typealias مع معاملات عامة؟

نعم، يمكن أن يتضمن typealias معاملات عامة: typealias Result<T> = Swift.Result<T, Error>. يتم توجيه المعاملات العامة إلى النوع الأصلي. لا يمكن إضافة قيود where — استخدم struct عامًا لذلك.

أين يمكن التصريح عن typealias؟

في أي مستوى: عام (في ملف)، داخل نوع (struct/class/enum)، داخل دالة، داخل بروتوكول (كـ associatedtype). يتم تحديد النطاق بمكان التصريح — typealias العامة مرئية في جميع أنحاء الوحدة، المحلية فقط داخل نطاقها.

متى يجب استخدام typealias بدلاً من الغلاف؟

اختر typealias لتقصير الأسماء الطويلة وتوثيق الدلالات عندما يكون التبادل مع النوع الأصلي آمنًا. اختر غلافًا (struct) عندما تحتاج إلى منع الخلط العرضي لمفاهيم مختلفة لنفس النوع الأساسي: UserID مقابل ProductID.

الخلاصة

  • Typealias — اسم مستعار لنوع موجود دون إنشاء نوع جديد؛ المترجم يستبدله بالأصلي
  • بناء الجملة: typealias NewName = ExistingType، النطاقات — عام، داخل نوع، داخل دالة
  • أنواع closure — typealias يبسط التواقيع: typealias Handler = (Int) -> Void
  • العامة — typealias يمكن أن يتضمن معاملات عامة لتقصير Result و Publisher وأنواع عامة أخرى
  • Associatedtype — typealias داخل بروتوكول، يتم تحديده بواسطة كل نوع يعتمده
  • الفرق مع الغلاف: typealias لا يعزل الأنواع — UserID و Int قابلان للتبادل؛ الغلاف (struct) يوفر أمانًا حقيقيًا للأنواع
  • أفضل ممارسة: استخدم typealias لسهولة القراءة، والأغلفة لمنع الأخطاء الدلالية في الترجمة

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا