Smart Cast on type of KClass<T> to T?


#1

I want to create a function to create class instances, based on the type of class that I pass as the function parameter.

I wrote the function like this:

class Foo
class Bar

private fun <T : Any> createDummyInstance(name: String, type: KClass<T>): T {
    val result: T = when (type) {
        Foo::class -> Foo()
        Bar::class -> Bar()
        String::class -> when (name) {
            "baseUrl" -> "http://localhost:8080/"
            else -> throw IllegalArgumentException("Don't know String property '$name'")
        }
        else -> throw IllegalArgumentException("Can't create instance of class ${type.simpleName}")
    } as T
    return result
}

At the end, I need to cast the result “as T” otherwise there’s a compiler error. The functions createTestShift() and createTestUser() return an instance of classes Shift and ApiUser respectively and the String case obviously returns a String instance.
Why cannot the compiler smart cast this? How should I write code like this, so that I do not need the explicit cast to T?


#2

The compiler can’t deduce that T is Foo from the fact that type is Foo::class because it’s not that smart yet. If you think this is worth supporting in the language, feel free to create an issue. However, I don’t think the compiler should deduce this because one can come up with examples of valid code (with unchecked casts) where this condition won’t hold.

The intended way is exactly how you’ve written + maybe suppression of the “unchecked cast” warning.