The typealias declaration allows you to create an alias for a type (and is therefore pretty accurately named!). You can specify a name that can be used in place of any given type of definition. If this type is quite complex, a typeAlias can be a useful way to simplify its use.
How to do it...
We will use a typealias to replace an array definition:
- First, let's create something we can store in an array. In this instance, let's create a Pug struct:
struct Pug {
let name: String
}
- Now, we can create an array that will contain instances of a Pug struct:
let pugs = [Pug]()
- We can set up a typealias to define an array of pugs as a Grumble:
typealias Grumble = [Pug]
- With this defined, we can substitute Grumble wherever we would use [Pug] or Array<Pug>:
var grumble = Grumble()
- However, this isn't some new type – it is just an array with all the same functionalities:
let marty = Pug(name: "Marty McPug")
let wolfie = Pug(name: "Wolfgang Pug")
let buddy = Pug(name: "Buddy")
grumble.append(marty)
grumble.append(wolfie)
grumble.append(buddy)
There's more...
The preceding example allows us to use types in a more natural and expressive way. In addition, we can use a typealias to simplify a more complex type that may be used in multiple places.
To see how this might be useful, we can partially build an object to fetch program information:
enum Channel {
case BBC1
case BBC2
case BBCNews
//...
}
class ProgrammeFetcher {
func fetchCurrentProgrammeName(forChannel channel: Channel,
resultHandler: (String?, Error?) -> Void) {
// ...
// Do the work to get the current programme
// ...
let exampleProgramName = "Sherlock"
resultHandler(exampleProgramName, nil)
}
func fetchNextProgrammeName(forChannel channel: Channel,
resultHandler: (String?, Error?) -> Void) {
// ...
// Do the work to get the next programme
// ...
let exampleProgramName = "Luther"
resultHandler(exampleProgramName, nil)
}
}
In the ProgrammeFetcher object, we have two methods that take a channel and a result handler closure. The result handler closure has the following definition. We have to define this twice; once for each method:
(String?, Error?) -> Void
Instead, we can define this closure definition with a typealias called FetchResultHandler and replace each method definition with a reference to this typealias:
class ProgrammeFetcher {
typealias FetchResultHandler = (String?, Error?) -> Void
func fetchCurrentProgrammeName(forChannel channel: Channel,
resultHandler: FetchResultHandler) {
// Get next programme
let programmeName = "Sherlock"
resultHandler(programmeName, nil)
}
func fetchNextProgrammeName(forChannel channel: Channel,
resultHandler: FetchResultHandler) {
// Get next programme
let programmeName = "Luther"
resultHandler(programmeName, nil)
}
}
Not only does this save us from defining the closure type twice, but it is also a better description of the function that the closure performs.
Using typealias doesn't affect how we provide closure to the method:
let fetcher = ProgrammeFetcher()
fetcher.fetchCurrentProgrammeName(forChannel: .BBC1,
resultHandler: { programmeName, error in
print(programmeName as Any)
})
See also
Further information about typealias can be found in Apple's documentation on the Swift language at http://swiftbook.link/docs/declarations.