Kotlin DDD Phantom type

Eugen Martynov on 2023-10-22

Kotlin DDD Phantom type

I was on twitter and got suggestion to read post-introduction about phantom type by Vincent Pradeilles. The idea is a code safety improvement with a minimum boilerplate and performance penalty.

The Kotlin equivalent would be next. Let’s pretend that you have code:

data class User(val id: String)
data class Address(val id: String)

val me = User(id = "test id")
val home = Address(id = "test id")

if (me.id == home.id) {
  assert("Wrong! Person can not be address")
}

Isuru Rajapakse came with the next improvement:

@JvmInline value class UserId(val value: String)
@JvmInline value class AddressId(val value: String)

data class User(val id: UserId)
data class Address(val id: AddressId)

val me = User(id = UserId("test id"))
val home = Address(id = AddressId("test id"))

if (me.id == home.id) {} // This will not compile

That has minimum performance penalty but still require some boilerplate code writing.

Then Ivan Canet proposed an improvement that will require also minimum boilerplate and will be 100% equivalent to the swift code:

@JvmInline value class Id<out T>(val value: String)

data class User(val id: Id<User>)
data class Address(val id: Id<Address>)

val me = User(id = Id("test id"))
val home = Address(id = Id("test id"))

if (me.id == home.id) {} // This will not compile also

That is neat!

This code works only with Kotlin JVM backend (JVM and Android) and Kotlin version 1.7.20+

Read more about: