Typealias — اعلانی در Swift که یک نام جایگزین برای نوع موجود بدون تعریف نوع جدید ایجاد میکند. نام مستعار در مرحله کامپایل کاملاً معادل نوع اصلی است — کامپایلر نوع اصلی را در هر جایی که typealias استفاده شده است جایگزین میکند. طبق Swift Language Guide (2025)، typealias برای کوتاهسازی سیگنچرهای طولانی، انتزاع نوعهای داخلی از طریق associatedtype در پروتکلها و سادهسازی پارامترهای generic پیچیده استفاده میشود. برخلاف wrapper نوع، typealias امنیت نوع اضافه نمیکند — این فقط یک نام مستعار است که توسط سیستم نوع تشخیص داده نمیشود.
نکات اصلی
typealias NewName = ExistingType — میتواند در هر سطحی اعلان شود (سراسری، محلی، داخل نوع)typealias Result = Swift.Result<Data, Error>typealias Handler = (Int) -> VoidTypealias — اعلانی در 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 برای تاپل خالی () است که سیگنچرهای تابع را خواناتر میکند.
از typealias برای مستندسازی معناشناسی نوع استفاده کنید، اما به یاد داشته باشید: این از ترکیب مفاهیم مختلف یک نوع پایه محافظت نمیکند. برای جداسازی ایمن نوع از wrapperها (struct wrapper) استفاده کنید.
Typealias با کلمه کلیدی typealias اعلان میشود، پس از آن نام جدید، علامت مساوی و نوع موجود میآید. فرم پایه:
typealias Name = ExistingType
typealias UserID = Int
typealias JSONDictionary = [String: Any]
حوزه دید typealias توسط محل اعلان تعیین میشود:
| سطح | مثال | دید |
|---|---|---|
| سراسری | typealias Name = String | کل ماژول (با در نظر گرفتن access control) |
| داخل نوع | 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 است. نوعهای closure در Swift میتوانند حجیم باشند، به خصوص با Optional و پارامترهای generic. Typealias (Data?, Error?) -> Void را به FetchResultHandler خوانا تبدیل میکند:
typealias FetchResultHandler = (Data?, Error?) -> Void
func fetchUser(id: Int, completion: FetchResultHandler) {
// درخواست شبکه
completion(data, nil)
}
طبق Ray Wenderlich Style Guide، typealias برای closure خوانایی سیگنچرهای متد را افزایش میدهد، به خصوص در پروتکلهای تفویض و الگوهای callback. اما از تعداد بیش از حد نامهای مستعار خودداری کنید — اگر closure در یک جا استفاده میشود، میتوان آن را inline اعلان کرد.
کتابخانه استاندارد Swift فعالانه از این روش استفاده میکند. به عنوان مثال، DispatchQueue.WorkItem — typealias برای DispatchWorkItem است، اگرچه از بیرون به عنوان یک نوع جداگانه به نظر میرسد. Typealias برای closure ابزاری برای خوانایی است، در آن زیادهروی نکنید: 3–5 نام مستعار closure در هر ماژول — حد معقول.
Typealias میتواند پارامترهای generic را شامل شود و نسخههای تخصصیشده از نوعهای عمومی ایجاد کند. این به ویژه هنگام کار با Result، Publisher و سایر نوعهای generic از کتابخانه استاندارد و Combine مفید است:
typealias FetchResult = Result<Data, Error>
typealias AnyPublisherOfData = AnyPublisher<Data, Error>
func loadData() -> FetchResult {
// بارگذاری داده
}
همچنین میتوان typealias با پارامترهای generic خود ایجاد کرد که به نوع اصلی هدایت میشوند:
typealias NetworkResult<T> = Result<T, NetworkError>
func fetchUser() -> NetworkResult<User> {
// ...
}
قانون مهم: typealias نمیتواند محدودیتهای generic جدید اضافه کند (where clauses) — فقط پارامترها را به نوع اصلی هدایت میکند. اگر محدودیتهای اضافی نیاز است، یک ساختار generic یا کلاس ایجاد کنید. طبق Swift by Sundell (2024)، typealias با generic — روشی ایدهآل برای کوتاهسازی سیگنچرهای تکراری در پروژههایی است که فعالانه از Combine، Result و async/await استفاده میکنند.
Associatedtype — typealias است که داخل پروتکل اعلان میشود و نوع وابسته را تعریف میکند. برخلاف typealias معمولی، associatedtype در مرحله اعلان به نوع خاصی متصل نیست — توسط هر نوعی که پروتکل را تأیید میکند مشخص میشود:
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
}
struct IntBox: Container {
typealias Item = Int
// پیادهسازی
}
struct StringBox: Container {
typealias Item = String
// پیادهسازی
}
Associatedtype به پروتکلها انعطافپذیری نوعهای generic را بدون مشخص کردن نوع خاص در محل اعلان میدهد. این اساس بسیاری از الگوهای Swift است: Collection (Element)، IteratorProtocol (Element)، Identifiable (ID). کامپایلر میتواند associatedtype را به طور خودکار از پیادهسازی استنتاج کند، بنابراین typealias Item = Int صریح اغلب حذف میشود — Swift Item را به عنوان Int از پارامتر متد append استنتاج میکند.
طبق Swift Evolution SE-0195 (2022)، opaque result types (some Container) برای کار با پروتکلهای حاوی associatedtype معرفی شد — این مشکل PAT (protocol with associated types) را حل کرد که نمیتوانستند به عنوان نوع متغیر استفاده شوند.
تفاوت کلیدی: typealias — فقط نام دیگری برای نوع موجود است، و wrapper — نوع جدیدی است که از نظر معنایی از اصلی جدا شده است. اگر typealias UserID = Int اعلان کنید، UserID و Int قابل جایگزینی هستند — تابعی که Int انتظار دارد UserID را بدون خطا میپذیرد.
Wrapper از طریق struct ایجاد میشود و امنیت نوع واقعی را فراهم میکند:
struct UserID: RawRepresentable {
let rawValue: Int
}
struct OrderID: RawRepresentable {
let rawValue: Int
}
// خطای کامپایل: نمیتوان OrderID را جایی که UserID مورد انتظار است ارسال کرد
طبق Point-Free (2025)، زمانی که مفاهیم مختلف با یک نوع پایه نمایش داده میشوند (UserID vs OrderID)، wrapperها ترجیح داده میشوند. Typealias زمانی توجیهپذیر است که هدف خوانایی بدون ایزولاسیون باشد: کوتاهسازی نام طولانی، مستندسازی معناشناسی، انتزاع پیادهسازی از طریق associatedtype. Typealias را برای راحتی خواندن انتخاب کنید، wrapper را — برای امنیت نوع.
سؤالات متداول
Typealias — نام مستعار برای یک نوع موجود خاص است. Associatedtype داخل پروتکل اعلان میشود و توسط هر نوع تأییدکننده پروتکل مشخص میشود — نوعهای مختلف میتوانند از associatedtype متفاوت برای یک پروتکل استفاده کنند.
خیر، typealias — فقط یک نام جایگزین است. کامپایلر آن را در مرحله کامپایل با نوع اصلی جایگزین میکند. برای ایجاد یک نوع جدید و معنایی جداگانه، از struct wrapper یا enum با rawValue استفاده کنید.
بله، typealias میتواند پارامترهای generic را شامل شود: typealias Result<T> = Swift.Result<T, Error>. پارامترهای generic به نوع اصلی هدایت میشوند. نمیتوان محدودیتهای where اضافه کرد — برای این کار از ساختار generic استفاده کنید.
در هر سطحی: سراسری (در فایل)، داخل نوع (struct/class/enum)، داخل تابع، داخل پروتکل (به عنوان associatedtype). حوزه دید توسط محل اعلان تعیین میشود — typealias سراسری در کل ماژول قابل مشاهده است، محلی — فقط در محدوده خود.
Typealias را برای کوتاهسازی نامهای طولانی و مستندسازی معناشناسی انتخاب کنید، زمانی که قابلیت جایگزینی با نوع اصلی ایمن است. Wrapper (struct) را — زمانی که باید از ترکیب تصادفی مفاهیم مختلف یک نوع پایه جلوگیری کرد: UserID در مقابل ProductID.
خلاصه
typealias NewName = ExistingType، حوزههای دید — سراسری، داخل نوع، داخل تابعtypealias Handler = (Int) -> Voidما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید