Clicky

iOS Dev Nugget 305 Declaring Distinct Types from General Types

.

Need to run a code review on your codebase? Hire me

I'm a big fan of using Swift's strong static typing to reduce bugs, and I recently stumbled upon a library that helps with that.

From the README, imagine you have this defined:

struct User {
  let id: Int
  let email: String
  let address: String
  let subscriptionId: Int?
}

struct Subscription {
  let id: Int
}

func fetchSubscription(byId id: Int) -> Subscription? {
  return subscriptions.first(where: { $0.id == id })
}

Notice that the id properties in both structs and subscriptionId properties are of type Int. This is pretty common. The problem is that Int is a very general type.

And if you call fetchSubscription(byId:) like this, you have introduced a bug:

let subscription = fetchSubscription(byId: user.id)

Strong static typing to the rescue! Tagged provides a simple way to solve it:

import Tagged

struct User {
  let id: Id
  let email: String
  let address: String
  let subscriptionId: Subscription.Id?

  typealias Id = Tagged<User, Int>
}

struct Subscription {
  let id: Id

  typealias Id = Tagged<Subscription, Int>
}

It basically lets you define unique types based off another type (the latter being Int in the example). So you can say that this struct's id and another struct's id property are of different types, despite both of them fundamentally being Int.

Your feedback is valuable: Do you want more nuggets like this?   Yes   or   No

.

.

Like this and want such iOS dev nuggets to be emailed to you, weekly?

Sign Me Up! or follow @iosdevnuggets on Twitter

.

View archives of past issues