Note2 min read

A typealias can take a type parameter

Naming a completion handler once and writing Handler<Post> at each call site. It gives you readability and a single place to change the signature. It does not give you type safety.

A typealias does one thing: it gives an existing type a second name. Apple’s own TimeInterval is one, aliasing Double. It says what the number means, and it leaves room for the underlying type to change without every mention of it changing too.

The version I use most often takes a type parameter:

struct Service {
  typealias Handler<Response> = (Result<Response, APIError>) -> Void

  func fetchPost(id: Int, _ completion: @escaping Handler<Post>) { ... }
  func fetchPosts(_ completion: @escaping Handler<[Post]>) { ... }
  func fetchBooks(_ completion: @escaping Handler<[Book]>) { ... }
}

Without it, each of those signatures carries (Result<Post, APIError>) -> Void in full, and the shape of the API — every call returns a Result with the same error type — is something the reader has to assemble from three lines that all look slightly different. With it, the shape is stated once and only the response type changes.

It also gives you somewhere to make a change. When the error type moves from APIError to something else, it moves in one line rather than in every signature that mentions it.

The other use is shortening a name you did not choose:

final class Service {
  typealias Book = SLBSomeLibraryServiceBookModel

  func loadBooks() -> [Book] { ... }
}

That is safe inside a type, where the alias is scoped and a reader can find the declaration. At file scope it needs more care: Book from three different modules means three different things.

What none of this gives you is type safety. Handler<Post> and (Result<Post, APIError>) -> Void are the same type, not two types that happen to be spelled differently — there is no distinction the compiler will enforce and no overload it will resolve differently. If you want the compiler to know that a service’s completion is not just any closure, the alias is the wrong tool and a wrapper type is the right one.

It is documentation that the compiler checks for spelling. It is not a type.

Antoine van der Lee has a longer piece on typealias that is worth the ten minutes.

Topics