When passing around strings or integers as IDs, the compiler doesn't tell you if you pass a person ID where a blog post ID. Now with the UniquelyTypedID
, the compiler will not let you pass the ID of a different model.
And with the power of ExpressibleByStringLiteral
and ExpressibleByIntegerLiteral
, very little code will need to change.
I've used this approach for typesafety of record IDs in my own projects, usually by manually copy-pasting. Now with Swift Macros in Swift 5.9, it's going to be so much easier.
Currently Int, String, and UUID are supported. And UUID is the default if no type is specified.
Start feeling safe and secure with type safe IDs today! Or more likely, when Swift 5.9 becomes generally available.
Example
If you had a integer ID like this
struct BlogPost {
let id: Int
let text: String
}
then you can use this macro instead.
struct BlogPost {
@UniquelyTypedId(Int.self) let id: ID
let text: String
}
And we can use it like so
let myPost = BlogPost(id: 3, text: "Hello world")
Easy to migrate from primitive IDs with conformance to ExpressibleByIntegerLiteral and ExpressibleByStringLiteral, and Codable conformance as a single value container.
Name of the ID type
The name of the generated ID type is whatever was specified. I personally like ID
, but here is an example using an arbitrary name.
struct Vegetable {
@UniquelyTypedId(String.self) let scientificName: ScientificName
let name: String
}
let chili = Vegetable(scientificName: "Capsicum annuum", name: "Chili")
GitHub link
GitHub doesn't yet support Swift 5.9, so the tests do not pass on GitHub Actions