Typealias è una dichiarazione in Swift che crea un nome alternativo per un tipo esistente senza definirne uno nuovo. L'alias è completamente equivalente al tipo originale in fase di compilazione — il compilatore sostituisce il tipo originale ovunque venga usato typealias. Secondo Swift Language Guide (2025), typealias viene utilizzato per abbreviare firme lunghe, astrarre tipi interni tramite associatedtype nei protocolli e semplificare parametri generici complessi. A differenza di un wrapper di tipo, typealias non aggiunge sicurezza dei tipi — è semplicemente un alias che il sistema dei tipi non distingue.
Punti chiave
typealias NewName = ExistingType — può essere dichiarato a qualsiasi livello (globale, locale, all'interno di un tipo)typealias Result = Swift.Result<Data, Error>typealias Handler = (Int) -> VoidTypealias è una dichiarazione in Swift che introduce un nome alternativo per un tipo esistente. Dopo aver dichiarato un typealias, il nuovo nome può essere usato ovunque sia previsto il tipo originale — il compilatore li tratta come identici. Typealias non aggiunge isolamento semantico: un valore di tipo UserID (typealias per String) può essere passato a una funzione che si aspetta String senza errore.
Gli scopi principali di typealias sono abbreviare nomi lunghi, documentare lo scopo di un tipo e astrarre l'implementazione concreta. Ad esempio, typealias JSON = [String: Any] indica esplicitamente che un dizionario viene usato come struttura JSON, e typealias Completion = (Result<Data, Error>) -> Void trasforma una firma di closure complessa in un tipo leggibile.
Secondo Swift.org (2025), typealias è ampiamente usato nella libreria standard. Ad esempio, String è un typealias per String (un Array<Character> specializzato), sebbene nelle versioni moderne di Swift questa implementazione sia nascosta. Void è un typealias per la tupla vuota (), che rende le firme delle funzioni più leggibili.
Usa typealias per documentare la semantica di un tipo, ma ricorda: non protegge dalla mescolanza di diversi concetti dello stesso tipo base. Per una separazione type-safe, usa wrapper (struct wrapper).
Typealias si dichiara con la parola chiave typealias, seguita dal nuovo nome, un segno di uguale e il tipo esistente. La forma base:
typealias Name = ExistingType
typealias UserID = Int
typealias JSONDictionary = [String: Any]
L'ambito di un typealias è determinato da dove viene dichiarato:
| Livello | Esempio | Visibilità |
|---|---|---|
| Globale | typealias Name = String | Intero modulo (soggetto a controllo accesso) |
| All'interno di un tipo | struct User { typealias ID = Int } | User.ID — accessibile tramite il tipo |
| All'interno di una funzione | func f() { typealias Local = Int } | Solo all'interno della funzione |
| All'interno di un protocollo | protocol P { associatedtype T } | Specificato al momento dell'adozione |
Typealias all'interno di un tipo (ad esempio, User.ID) è un pattern comune per raggruppare alias correlati. Ciò migliora il namespacing: Order.ID e User.ID sono entrambi Int, ma vengono letti come concetti diversi. L'accesso a un typealias annidato avviene tramite User.ID o tramite notazione puntata se il tipo è noto.
Uno degli usi più comuni di typealias è semplificare le firme delle closure. I tipi closure in Swift possono essere ingombranti, specialmente con Optional e parametri generici. Typealias trasforma (Data?, Error?) -> Void in un leggibile FetchResultHandler:
typealias FetchResultHandler = (Data?, Error?) -> Void
func fetchUser(id: Int, completion: FetchResultHandler) {
// network request
completion(data, nil)
}
Secondo la Guida di Stile di Ray Wenderlich, typealias per le closure migliora la leggibilità delle firme dei metodi, specialmente nei protocolli di delega e nei pattern di callback. Tuttavia, evita alias eccessivi — se una closure viene usata in un solo punto, può essere dichiarata inline.
La libreria standard di Swift utilizza attivamente questo approccio. Ad esempio, DispatchQueue.WorkItem è un typealias per DispatchWorkItem, sebbene esternamente sembri un tipo separato. Typealias per le closure è uno strumento di leggibilità — non abusarne: 3–5 alias di closure per modulo è un limite ragionevole.
Typealias può includere parametri generici, creando versioni specializzate di tipi generici. Ciò è particolarmente utile quando si lavora con Result, Publisher e altri tipi generici della libreria standard e Combine:
typealias FetchResult = Result<Data, Error>
typealias AnyPublisherOfData = AnyPublisher<Data, Error>
func loadData() -> FetchResult {
// data loading
}
Puoi anche creare typealias con parametri generici personalizzati che vengono inoltrati al tipo originale:
typealias NetworkResult<T> = Result<T, NetworkError>
func fetchUser() -> NetworkResult<User> {
// ...
}
Una regola importante: typealias non può aggiungere nuove restrizioni generiche (clausole where) — si limita a inoltrare parametri al tipo originale. Se sono necessarie restrizioni aggiuntive, crea una struct o una classe generica. Secondo Swift by Sundell (2024), typealias con i generici è un modo ideale per abbreviare firme ripetitive in progetti che usano intensamente Combine, Result e async/await.
Associatedtype è un typealias dichiarato all'interno di un protocollo che definisce un tipo associato. A differenza di un typealias normale, associatedtype non è legato a un tipo specifico al momento della dichiarazione — viene specificato da ogni tipo che adotta il protocollo:
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 conferisce ai protocolli la flessibilità dei tipi generici senza specificare un tipo concreto nel punto di dichiarazione. Questa è la base di molti pattern Swift: Collection (Element), IteratorProtocol (Element), Identifiable (ID). Il compilatore può inferire associatedtype automaticamente dall'implementazione, quindi un esplicito typealias Item = Int viene spesso omesso — Swift inferisce Item come Int dal parametro del metodo append.
Secondo Swift Evolution SE-0195 (2022), sono stati introdotti i tipi di risultato opachi (some Container) per lavorare con protocolli che contengono associatedtype — ciò ha risolto il problema PAT (protocollo con tipi associati), che impediva di usare tali protocolli come tipi di variabile.
La differenza chiave: typealias è solo un altro nome per un tipo esistente, mentre un wrapper è un nuovo tipo, semanticamente isolato dall'originale. Se dichiari typealias UserID = Int, allora UserID e Int sono intercambiabili — una funzione che si aspetta Int accetterà UserID senza errore.
Un wrapper viene creato tramite struct e fornisce vera sicurezza dei tipi:
struct UserID: RawRepresentable {
let rawValue: Int
}
struct OrderID: RawRepresentable {
let rawValue: Int
}
// Compilation error: cannot pass OrderID where UserID is expected
Secondo Point-Free (2025), i wrapper sono preferibili quando diversi concetti sono rappresentati dallo stesso tipo base (UserID vs OrderID). Typealias è giustificato quando l'obiettivo è la leggibilità senza isolamento: abbreviare nomi lunghi, documentare la semantica, astrarre l'implementazione tramite associatedtype. Scegli typealias per la comodità di lettura, wrapper per la sicurezza dei tipi.
Domande frequenti
Typealias è un alias per un tipo esistente specifico. Associatedtype viene dichiarato all'interno di un protocollo e viene specificato da ogni tipo che adotta il protocollo — tipi diversi possono usare associatedtype diversi per lo stesso protocollo.
No, typealias è solo un nome alternativo. Il compilatore lo sostituisce con il tipo originale in fase di compilazione. Per creare un nuovo tipo semanticamente isolato, usa un struct wrapper o un enum con rawValue.
Sì, typealias può includere parametri generici: typealias Result<T> = Swift.Result<T, Error>. I parametri generici vengono inoltrati al tipo originale. Non è possibile aggiungere clausole where — per questo usa una struct generica.
A qualsiasi livello: globale (in un file), all'interno di un tipo (struct/class/enum), all'interno di una funzione, all'interno di un protocollo (come associatedtype). L'ambito è determinato dalla posizione della dichiarazione — i typealias globali sono visibili nell'intero modulo, quelli locali solo nel loro ambito.
Scegli typealias per abbreviare nomi lunghi e documentare la semantica quando l'intercambiabilità con il tipo originale è sicura. Scegli un wrapper (struct) quando devi prevenire la mescolanza accidentale di diversi concetti dello stesso tipo base: UserID vs ProductID.
Riepilogo
typealias NewName = ExistingType, ambiti — globale, all'interno di un tipo, all'interno di una funzionetypealias Handler = (Int) -> VoidSvilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche