Kotlin DDD Phantom type

🇺🇦 Eugen Martynov
2 min readOct 22, 2023

--

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:

--

--

🇺🇦 Eugen Martynov
🇺🇦 Eugen Martynov

Written by 🇺🇦 Eugen Martynov

Stand with Ukraine! The loving XP husband and freelance Android/Kotlin engineer.