Typealias in Swift: 3 use cases
First things first, what is a typealias?
A typealias allows us to give a custom name to a specific type. Simple as that. It’s not a new type, it’s just a semantic abstraction for a specific type.
However, it's a powerful feature. We can improve our code base by making it more readable and easier to work on.
This feature can make our code more readable and easier to work on. Let’s see 3 simple scenarios where we can use it.
We define it using the keyword typealias
typealias {name} = {type}
. Then, we can use the alias in any part of the code we want to reference {type}.
1. Better semantic
Providing context in our code and making it self-documented is always a good practice.
Swift itself uses typealias
to add semantic and domain-specific code. Have you ever used TimeInterval
type? It's a typealias
for Double
type.
typealias Miles = Double
class RunningWorkout {
let date: Date
let distance: Miles
let calories: Int
}
We could have used Double
for distance
property. But, doing it that way, if we wanted a self-document code, we probably would use a different name for the property — like distanceInMiles
.
The same principles apply to other types like Dictionaries
or Tuples
.
typealias ApiHeaders = [String: String]
func getHeaders() -> ApiHeaders {
var headers = ApiHeaders()
headers["x-api-token"] = "asf232asgf5"
headers["content-type"] = "application/json"
return headers
}
typealias EndpointInformation = (path: String, method: String)
let getRunningWorkgouts = EndpointInformation(path: "/workouts/running", method: "GET")
2. Reduce code complexity
Although with the release of async/await
we should be using fewer completion handlers, in some situations, we might have no alternative but to use them.
typealias RunningHandler = ([RunningWorkout]) -> Void
func getRunningWorkouts(_ handler: @escaping RunningHandler) { ... }
We can use a typealias as a shortcut if we have some nested type.
enum WorkoutType {
enum Running {
case speed
case tempo
case interval
}
enum Weightlifting { ... }
}
typealias Running = WorkoutType.Running
We also can use typealias
to group different protocols in one.
Look at
Codable
protocol definition:typealias Codable: Encodable & Decodable
3. Generics
We can use everything we saw previously combined with generics.
struct NetworkClient<Resource> {
typealias CompletionHandler = (Result<Resource, Error>) -> Void
func fetchAll(using endpoint: EndpointInformation, _ completion: @escaping CompletionHandler) {}
}
typealias RunningWorkoutClient = NetworkClient<RunningWorkout>
let client = RunningWorkoutClient()
client.fetchAll(using: getRunningWorkouts) { result in
switch result {
case .success(let workout):
print("Workout distance: \(workout.distance)")
case .failure(let error):
print("Error: \(error.localizedDescription)")
}
}
Takeaways
- Enhanced Readability: Providing meaningful names with
typealias
for complex types will help create more readable and maintainable code. - Reusability: Using
typealias
for generic types will promote a modular approach. - Abstraction:
typealias
offers an elegant way to create more adaptable and flexible code. Devs can easily adapt types without impacting the entire codebase.