Search code examples
kotlinextendssealed-class

sealed class extends other sealed class


I am making various state models and side effect classes while using the MVI pattern. The state model can reduce the boilerplate by extending the interface that collects common parts, but the side effect class does not support extends as it is a sealed class. So I see the Toast side effect as boilerplate code. How can I get rid of this Toast side effect boilerplate code? Is there any way for the sealed class to extend to other sealed classes?

My state classes:

interface BaseMviState {
    val loaded: Boolean
    val exception: Exception?

    fun isException() = exception != null
}

data class MviJoinState(
    override val loaded: Boolean = false,
    override val exception: Exception? = null,
    val loginResult: Boolean = false,
    val registerResult: Boolean = false,
) : BaseMviState

data class MviRoomCreateState(
    override val loaded: Boolean = false,
    override val exception: Exception? = null,
) : BaseMviState

My side effect classes:

sealed class MviJoinSideEffect {
    data class SetupAutoLogin(val user: User) : MviJoinSideEffect()
    data class Toast(val message: String) : MviJoinSideEffect() // boilerplate
}

sealed class MviRoomCreateSideEffect {
    data class Toast(val message: String) : MviRoomCreateSideEffect() // boilerplate
}

Solution

  • I solved this problem by extending the interface in a sealed class like this:

    sealed interface BaseEvent {
        data class Toast(val toastMessage: String) : BaseEvent
    }
    
    sealed class Event : BaseEvent {
        data class Snackbar(val snackbarMessage: String) : Event()
    }
    
    fun main() {
        val event: BaseEvent = Event.Snackbar("Hi")
    
        when (event) {
            is BaseEvent.Toast -> todo(event.toastMessage)
            is Event.Snackbar -> todo(event.snackbarMessage)
        }
    }
    
    fun todo(message: String) {}