Generic Enum of certain type

I would like to enforce, at compile time, the type of a parameter to an Enum that also implements an interface:

interface MyInterface {
    val value: String
}

enum class WrongTypeEnum {
    WrongEnum1,
    WrongEnum2,
}

enum class CorrectTypeEnum(override val value: String) : MyInterface {
    CorrectEnum1("value1"),
    CorrectEnum2("value2");
}

If I write a generic function, things work correctly:

fun <T : Enum<out MyInterface>> myFunction(param: T) {...}

myFunction(CorrectTypeEnum.TestEnum1)     // compiles successfully
myFunction(WrongTypeEnum.WrongEnum1)  // correctly shows compile error

Problem is that things don’t work the same way if it’s a generic class:

class MyClass<T : Enum<out MyInterface>>
// The above line shows the following compile time error:
//    Type argument is not within its bounds.
//    Expected: Enum<out MyInterface>
//    Found: MyInterface

So, question is: what am I doing wrong and how can I make it that MyClass can by typed to enum classes that also implement MyInterface?

You need to type this instead:

class MyClass<T> where T : Enum<T>, T : MyInterface
2 Likes