Swift, more elegant code: Typealias

Ahmad Fayyas
5 min readJan 10, 2018

--

Are you facing troubles with long-signature functions? do you think that renaming some of the types would be a good idea? well… just take a look at typealias.

What is typealias?

For the first time I figured out that there is something called “Aliases” it was a bit weird for me, even after knowing what it does, it seemed to me that there is no “good” point of using it; So far I’m a fan of it!

Before jumping to Swift typealias, I would like to note that the alias is not an exclusive term for Swift programming language, actually it is a computing term, you could find the logic of “Aliasing” in many other old-school and modern (such as Swift) programming languages…

Typealias is a named alias of an existing type, meaning that by using it you would be able to name types to be more convenient to your program. Keep in mind that typealias is not new types, it is just name to existing type, you could consider it as an alternative name for a type (it could be a “shortcut” as you will read soon).

How to implement typealias?

Simply, you would implement a typealias as:

typealias yourCustomName = existing type

and that all it takes!

Let’s start doing some pretty simple code:

Implementing:

typealias Strings = [String]

lets you declare variables -for instance- of type Array of Strings ([String]) as follows:

var strs: Strings?

Now strs would be a variable of type [String] .

Pretty interesting! Honestly, for me I don’t think so. If you were thinking of “so far, it is useless”, I would kind of agree that 😅.

There is no doubt that creating a typealias for such a case would not be that useful, in some cases, declaring it as var strs: [String]? would be even better to read… Just calm it down, let’s try another one: what about declaring a typealias for a Dictionary of Strings as keys and Integers for values:

typealias CustomDict = Dictionary<String, Int>

that should save some “effort” when it comes to declare the concrete types of the generic parameters for the Dictionary (<String, Int>), it is like “bilateral 2 in 1 saving”! However, still not that good reason for using typealias, right? That leads to:

Why to use typealias?

As a real case, usually when working with a non-trivial app, it should has its own managers for handling tasks for a specified functionality, such as sending and receiving data over a network connection, fetching the device photos (accessing system resources), writing and reading data from/into the disk and so on… Thus implementing these managers might require “pretty long” signatures for their methods. Let’s take one step further and do some code for more “real world” case:

Example:

To make it more straightforward, I’ll focus on the signatures of the methods, regardless of what are the actual inner implementation of them (the manager purpose).

Consider that we have MyManager which includes foo and bar methods as follows:

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(..., ..., ...)
}
}

// ...
}

So far so good, but wait a second… these method signatures looks really tedious! both of them take success and failure parameters, and I bet you noticed that they are the same for both of methods:

success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()

and

failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()

As aside bar note, in your real app, you might need to declare these closures as Escaping Closures

which could end up with a confusing signature to be read…

Based on our case, when it comes to work with compound types, you would definitely notice the benefits of declaring typealiases.

Typealias is here to save you! So yes, you could let these closure signatures to be typealiases:

typealias Success = (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()typealias Failure = (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()

Thus:

class MyManager {
//...

func foo(success: Success, failure: Failure) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}

func bar(success: Success, failure: Failure) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}

// ...
}

Much better! At this point it should be more expressive and readable.

Also from the “reusability” point of view, for implementing similar functions, it would be much easier to use the typealias instead of keeping “copy-paste” the parameters; Editing the declaration of the typealias would be reflected on all the manager method signatures.

Wrapping Up:

Typealiases are useful, even Swift itself uses them, as a pretty example Codable is a typealias for both Decodable and Encodable protocols. However, keep in mind that you should not overuse them, sometimes it would be unnecessary to declare such a typealias (typealias Strings = [String] 😄), just do it when you believe that it is useful.

Reference:

Author ✍️

Appreciate your feedback 👏 Stay tuned for more “Swift, more elegant code” topics.

Thanks for Reading!

--

--

Ahmad Fayyas

Software Engineer. If I’m not in front of my pc coding or playing video games, you can find me hanging out with family and friends, or sleeping!