Typealias in Swift: 3 use cases

Bruno Lorenzo
3 min readNov 14, 2023

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

  1. Enhanced Readability: Providing meaningful names with typealias for complex types will help create more readable and maintainable code.
  2. Reusability: Using typealias for generic types will promote a modular approach.
  3. Abstraction: typealias offers an elegant way to create more adaptable and flexible code. Devs can easily adapt types without impacting the entire codebase.

Have any questions? Feel free to drop me a message! 🙂

  • 🤓 Join me on X for regular content on iOS development tips and insights
  • 🚀 Check out my GitHub where I share all my example projects

--

--

Bruno Lorenzo

Software Engineer | Innovation Manager at www.houlak.com | Former iOS Tech Lead | I write about iOS, tech, and producitivy