When returning Generic type * I get error not enough information to infer type variable T

Viewed 605

I have the following code -


// My function - 
suspend fun leaveGroup(isSoloGroup: Boolean, groupMemberEntity: GroupMemberEntity): Resource<*> {

        val snapShot = remoteDataSource.getSnapshot(GROUP_MEMBERS_COLLECTION) {
            whereEqualTo(Constants.DatabaseProperties.ID, groupMemberEntity.id)
        }

        if (snapShot is Resource.Exception) {
            return snapShot
        }

        val delete = remoteDataSource.deleteSnapshot(snapShot.data!!)
        if (delete is Resource.Exception) {
            return delete
        }

        if (isSoloGroup.not()) {
            return (Resource.Success()) // This is where the error occurs 
        }
        // Code continues ...
    }


//My resource class - 

sealed class Resource<T> {

    abstract val data: T?

    data class Success<T>(override val data: T? = null) : Resource<T>()

    data class Exception<T>(val throwable: Throwable, override val data: T? = null) : Resource<T>()

    data class Loading<T>(val hasStarted: Boolean = false, override val data: T? = null) : Resource<T>()

}

And for some reason when I am returning the type Resource<*> the class Resource. Success can't be instantiated with its default value null and I must explicitly give it a null value - otherwise I will get the error saying Not enough information to infer type variable T. Giving it null in the constructor obviously works, but this is not Clean Code and makes the default value redundant. What am I missing?

1 Answers

There is a Nothing type in the type system, which has no values, it cannot be instantiated.

Because Nothing has no values, Nothing? is actually the type that captures only the null value in Kotlin.

That is, when you declare something like this:

val someVariable = null

The inferred type of someVariable is Nothing?

So if you wish to store the null, you have to give it a type (compiler cannot infer it directly as it can be anything like String?, Int?, etc.), So giving it explicit Nothing? is more appropriate.

if (isSoloGroup.not()) {
    return Resource.Success<Nothing>()
}
Related