Search code examples
kotlingenericsextension-methodstype-level-computation

Kotlin: Extension function to widen list type param (or any covariant type param)


I need an extension function to widen the type of covariant container like a List.

So imagine the following scenario:

val listOfInts = listOf(1,2,3,4,5)

val listOfNumbers = listOfInts.widen<Number>() //would be of type List<Number>

I just can't manage to achieve that.

I could write the following:


fun <U:Any,T:U> List<T>.widen():List<U> = this

But then, it needs to be invoked like:

listOfInts.widen<Number,_>()

YEAH! I know, it's just 2 extra characters, but they ruin the ergonomics of the library I'm writing

Help, please!


Solution

  • I was noodling on ways to accomplish this, reading up on generics, and the documentation itself has a function for this. It may be overkill with the type checking and nulling, but it is safer.

    More Strict:

    fun <T> List<T>.widen(): List<T> = this
    

    Less Strict: From Documentation

    inline fun <reified T> List<*>.asListOfType(): List<T>? =
        if (all { it is T })
            @Suppress("UNCHECKED_CAST")
            this as List<T> else
            null