I got a sealed interface like this ```internal sea...
# getting-started
s
I got a sealed interface like this
Copy code
internal sealed interface SomeUiState {
  data class Success(val isReloading: Boolean = false): SomeUiState
  data object Error : SomeUiState
}
And I want to add a convenience
val isReloading: Boolean
to the interface itself to not have to check if it is Success first before actually checking the isReloading property, so avoid having to each time do
(uiState is Success).isReloading
but be able to just call
uiState.isReloading
What I initially thought I could do was this
Copy code
internal sealed interface SomeUiState {
  val isReloading: Boolean
    get() = return this is Success && isReloading
  data class Success(override val isReloading: Boolean = false): SomeUiState
  data object Error : SomeUiState
}
But I can’t really do that since then
this.isReloading
refers back to itself, doing an infinite recursive call. What I can do instead is
Copy code
val isReloading: Boolean
  get() = this is Success && (this as Success).isReloading
But now I am doing a cast to Success which the IDE warns me is redundant, but if I do apply the quick fix I break my code. So the question is, am I missing some better approach on how I can write this instead?
Okay and I feel like I’ve rubber ducked myself, since I tried to make in an extension function instead and how it looks good
Copy code
internal val HomeUiState.isReloading: Boolean
  get() = this is HomeUiState.Success && this.isReloading
Which I feel like is my best bet here.
👍 2
rubber duck 1
b
A question on the above, as I am not fully comprehending properties.
Copy code
internal val HomeUiState.isReloading = this is HomeUiState.Success && this.isReloading
Would this code be equivalent?
🚫 1
a
if I may offer an alternative, you could add
isReloading
to the interface and implement it in
Error
Copy code
internal sealed interface SomeUiState {
  val isReloading: Boolean 
  
  data class Success(
      override val isReloading: Boolean = false
  ): SomeUiState
  
  data object Error : SomeUiState {
    override val isReloading: Boolean
      get() = false
  }
}
1
s
Yeah I considered this too Adam, and thank you for the idea, but in my real interface I got more than 1 other implementations, and it felt a bit worse of an option to have to make all of those implement something that they really don’t care about.
a
yeah, it depends on your situation of course. An extension function is certainly useful. A slight refinement: you could add a default implementation in the interface, so only specific subtypes need to implement `isReloading`:
Copy code
internal sealed interface SomeUiState {
  val isReloading: Boolean
    get() = false

  data class Success(
      override val isReloading: Boolean = false
  ): SomeUiState

  data object Error : SomeUiState
}
👍 1
s
Bram, it would actually not even compile as it is, if you try it on your IDE it will show you the error
b
Yeah, I figured re-reading the code, getting a bit confused with this syntax 😄 but trying not to derail your thread, sorry!
s
Heh no worries!
Oh yes! This is even better wow I really did not think about it. Thanks so much Adam! No extra work on the other implementations, and also no need to create a new extension function, which is outside of the brackets of the interface, which makes it a bit less discoverable in case the code grows even more. You git the spot with this one 🌟
fist bump 2
k
What you had originally works just fine:
Copy code
get() = this is Success && isReloading
It's not a recursive call at all. It's a virtual method call. The only problem is that IDEA gives you a false warning.
If you don't want to see the false warning, the following also works:
Copy code
get() = (this as? Success)?.isReloading == true
s
When I actually run some tests that were using it they were giving me “tests were not received” error, which made me think was just not working, something that was fixed as I changed my code to what we said above. So this did not give me a lot of confidence. Besides,
get() = false
feels much cleaner than
(this as? Success)?.isReloading == true
since I’d need to write
overrides
anyway, so I don’t see this being a better option, having to do an extra cast there and all.