Deduce type of argument of a Generic class

Hi there,

Assume, we have classes:

abstract class Descriptor<E : Enum<E>> {
  abstract fun getEnum():  E
class First: Descriptor<First.Variant> {
  enum class Variant{ A, B }
  override fun getEnum():  Variant = Variant.A
class Second: Descriptor<Second.Variant> {
  enum class Variant{ C, D }
  override fun getEnum():  Variant = Variant.C

Is there a way not to declare the class parameter if I want to use Descriptor.E,
now I have to do this:

inline fun <refied T: Descriptor<E>, E: Enum<E>> getVariant() = T().getEnum()

// here, I would like NOT to add second parameter, assuming it can be deduced
val enum1 = getVariant<First, First.Variant>()
val enum2 = getVariant<Second, Second.Variant>()

I would like to have call looking like:

val enum1 = getVariant<First>()
val enum2 = getVariant<Second>()

I don’t think this is possible. Some connected issues:

So currently it’s only possible to either include all or none type parameters.
Depending on specific use case you may try the second approach, providing types via parameters and type of variable you assign result to - see example in first comment from second link.

For the specific example, where you instantiate your class within getVariant function, you may consider passing KClass as parameter instead of using reified type parameters - technically you only write the name of the class and not the name of enum class :wink:

fun <T: Descriptor<E>, E : Enum<E>> getVariant(t: KClass<T>) = t.createInstance().getEnum()

And call

val enum1 = getVariant(First::class)  // First.Variant is inferred
val enum2 = getVariant(Second::class) // Second.Variant is inferred
1 Like