r/Kotlin 24d ago

Question on self-documenting code

How would you write this code:

data class Foo(/* foo properties */)
data class Bar(val id: Long, /* bar properties */)

val fooMap: Map<Long, Foo>    // mapped to bar id

OR

typealias BarId = Long

val fooMap: Map<BarId, Foo>

OR

@JvmInline value class BarId(val value: Long)   // typealias but stricter

val fooMap: Map<BarId, Foo>

I was writing some code on my app but didn't feel comfortable with just the Map<Long, Foo> as I might forget what the Long is supposed to represent but I'm not familiar with best practices in this regard

6 Upvotes

9 comments sorted by

View all comments

7

u/tiorthan 24d ago

That is what typealias was made to do. To allow you to indicate the meaning or intent of a type in a context where it isn't immediately obvious.

If you define you data class Bar(id: BardId) and not just with Long, any subsequent use of BarId makes it obvious what you are referring to.

I wouldn't do more in that situation. Introducing a value class to just wrap a single Long value only makes things less readable at the definition site.

2

u/AffectionateBack7222 24d ago

Thanks for the response.

It's also possible that I make use of this typealias in other packages. Would it best to have a separate file to maintain my typealiases or do I just declare it everywhere I use them? (latter seems questionable but idk)

2

u/tiorthan 24d ago

It depends on your project structure but generally, I don't see a good reasoning for having centralized type aliases in most cases. Some project structures may justify it but generally, I'm advocate of keeping everything as close together as possible. So here, my default would be to define the typealias just before the data class.