I have a function which checks its generic type parameter, and if the type is one of the expected values, does something with it appropriate for that type. If the type is unexpected, it throws an exception.
inline fun <reified T> convert(functionName: String, vararg args: Any?): T {
val obj: Any = executeJSFunction(functionName, *args)
val builtInClasses = arrayOf<KClass<*>>(Int::class, String::class, Boolean::class)
@Suppress("UNCHECKED_CAST")
return when {
T::class in builtInClasses ->
obj as T
T::class.companionObjectInstance as? DataClassFactory<T> != null ->
(T::class.companionObjectInstance as DataClassFactory<T>).fromV8Object(obj as V8Object)
else ->
throw IllegalArgumentException("No converter for type ${T::class}")
}
}
This works, but it's doing the check at runtime. I'd like to find a way of getting a compilation error, instead of a runtime exception, if the generic type parameter is not one of the expected types. Is this possible, perhaps with contracts?
// should compile, as Int is one of the supported types
val intResult: Int = convert("intFunction")
// should fail to compile, as Double is unsupported
val doubleResult: Double = convert("doubleFunction")