Typealias to mechanizm tworzenia pseudonimów dla istniejących typów, który ułatwia czytanie kodu, poprawia wsparcie projektów i pozwala na ponowne wykorzystanie abstrahencji.
Historia pytania
Typealias pojawił się jako dziedzictwo z wielu innych języków, na przykład typedef w C. W Swift typealias jest zintegrowany z systemem typów i jest aktywnie stosowany dla typów generycznych oraz protokołów z associated type.
Problem
W dużych projektach często występują długie typy generyczne, typy złożone, kompozycje i zagnieżdżone typy. Bez pseudonimów takie konstrukcje stają się nieczytelne i utrudniają wsparcie aplikacji.
Rozwiązanie
Deklaracja typealias dla często używanych lub złożonych typów sprawia, że kod jest prostszy, bardziej zrozumiały i bardziej strukturalny. Typealias często stosuje się również do określenia pseudonimów protokołów z associatedtype, aby obejść ograniczenia protokołów jako typów.
Przykład kodu:
typealias JSON = [String: Any] typealias CompletionHandler = (Result<Int, Error>) -> Void typealias StringDictionary = Dictionary<String, String> typealias Handler = (String) -> Void
Kluczowe cechy:
Czy można stworzyć nowy typ za pomocą typealias?
Nie, typealias nie tworzy nowego typu — to tylko pseudonim, pełna synonimia istniejącego typu, a kompilator traktuje je jako ten sam typ.
typealias Age = Int let a: Age = 25 let b: Int = a // Wszystko poprawnie
Czy typealias będzie działać na poziomie bezpieczeństwa typów (type safety)?
Nie, typealias nie chroni przed przekazywaniem niewłaściwego typu: JSON i [String: Any] są wymienne. Aby kontrolować lub dzielić logikę, należy użyć oddzielnych struktur/obiektów opakowujących, a nie typealias.
typealias UserID = Int typealias ProductID = Int func logId(_ id: UserID) {} let productId: ProductID = 42 logId(productId) // Kompilator nie zgłasza błędu!
Czy można deklarować typealias wewnątrz protokołów lub typów generycznych?
Tak, wewnątrz protokołów często deklaruje się associatedtype lub typealias, szczególnie dla złożonych typów generycznych lub niestandardowych interfejsów.
protocol DataSource { associatedtype Item typealias CompletionBlock = (Item) -> Void }
Wszystkie identyfikatory modeli są zadeklarowane za pomocą typealias jako Int:
typealias UserID = Int typealias ProductID = Int func deleteUser(id: UserID) func deleteProduct(id: ProductID)
Zalety:
Dla złożonych typów generycznych lub wyników typu closure, zadeklarowano typealias:
typealias Completion<T> = (Result<T, Error>) -> Void let completion: Completion<String>
Zalety: