Search code examples
swifttype-alias

When to use typealias?


So far I understand that the typealias is a named alias of an existing type. By using typealias, I could do something like:

typealias MyString = String
var str: MyString?

typealias Strings = [String]
var strs: Strings?

which leads to declare str variable as String and strs as an Array of strings.

Even for a custom type:

class MyClass {}
typealias MyClsType = MyClass
var myClass: MyClsType

However, it seems a little unuseful; Logically, what is the purpose of declaring -for example- var str: MyString? to be a String instead of var str: String?? even more, var str: String is more expressive.


Solution

  • Actually, there is no doubt that creating a typealias for -let's say- String: typealias MyString = String wouldn't be that useful, (I would also assume that declaring a typealias for Dictionary with specific key/value type: typealias CustomDict = Dictionary<String, Int> might not be that useful to you.

    However, when it comes to work with compound types you would definitely notice the benefits of type aliasing.

    Example:

    Consider that you are implementing manager which repeatedly work with closures with many parameters in its functions:

    class MyManager {
        //...
    
        func foo(success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> (), failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()) {
            if isSuccess {
                success(..., ..., ..., ...)
            } else {
                failure(..., ..., ...)
            }
        }
    
        func bar(success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> (), failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()) {
            if isSuccess {
                success(..., ..., ..., ...)
            } else {
                failure(..., ..., ...)
            }
        }
    
        // ...
    }
    

    As you can see, the methods signatures looks really tedious! both of the methods take success and failure parameters, each one of them are closures with arguments; Also, for implementing similar functions, it is not that logical to keep copy-paste the parameters.

    Implementing typealias for such a case would be so appropriate:

    class MyManager {
        //...
    
        typealias Success = (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()
        typealias Failure = (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()
    
        func foo(success: Success, failure: Failure) {
            if isSuccess {
                success(..., ..., ..., ...)
            } else {
                failure(..., ..., ...)
            }
        }
    
        func bar(success: Success, failure: Failure) {
            if isSuccess {
                success(..., ..., ..., ...)
            } else {
                failure(..., ..., ...)
            }
        }
    
        // ...
    }
    

    Thus it would be more expressive and readable.


    Furthermore, you might want to check a medium story I posted about it.