Home > database >  Generic Enum type parameter with required interface
Generic Enum type parameter with required interface

Time:01-13

I have an interface that looks like the following:

interface LabelledEnum {
    fun getLabelId(): Int
}

I inherit this interface in an enum class as follows:

enum class Period : LabelledEnum {
    YTD {
        override fun getLabelId(): Int =
            R.string.ytd_label
    },
    ONE_MONTH {
        override fun getLabelId(): Int =
            R.string.1m_label
    },
    THREE_MONTHS {
        override fun getLabelId(): Int =
            R.string.3m_label
    },
    SIX_MONTHS {
        override fun getLabelId(): Int =
            R.string.6m_label
    },
    ONE_YEAR {
        override fun getLabelId(): Int =
            R.string.1y_label
    },
    THREE_YEARS {
        override fun getLabelId(): Int =
            R.string.3y_label
    },
    FIVE_YEARS {
        override fun getLabelId(): Int =
            R.string.5y_label
    },
    MAX {
        override fun getLabelId(): Int =
            R.string.max_label
    };
}

I have a custom composable I am working on where I want to make it generic (use type parameters instead of hardcoding things) but I am struggling to find a way to implement this generic type parameter such that the type parameter is necessarily an Enum that inherits my interface LabelledEnum.

So far, my composable looks like this:

@Composable
inline fun <reified T : Enum<T>> CustomTabRow(
    selectedEnum: T,
    crossinline onEnumSelected: (T) -> Unit,
    modifier: Modifier = Modifier,
) {
    // Things happen here
}

Is there a way to ensure that the type parameter T is an Enum AND inherits from LabelledEnum ?

If not, I'll use a workaround but I'd really prefer to make this work if at all possible

CodePudding user response:

Kotlin has a where syntax to express constraints like this.

@Composable
inline fun <reified T> CustomTabRow(
    selectedEnum: T,
    crossinline onEnumSelected: (T) -> Unit,
    modifier: Modifier = Modifier,
) where T : Enum<T>, T : LabelledEnum  {
    // Things happen here
}

Note that you have to move T : Enum<T> to the where clause.

  •  Tags:  
  • Related