I'm wondering whether it's possible to create a generic class, that accepts an instance of type T
, which is limited to (e.g.) an instance of String
or an instance of List<String>
. See the following pseudo code as an example:
data class Wrapper<T : String | List<String>>(val wrapped: T)
This closely resembles the Union
construct, which does not exist in Kotlin (by design). I'm curious whether this can be achieved in a compile time check.
The pseudo code class presented above would be used to provide a single object instance of String
, and if multiple instances are provided, then it should be a List<String>
.
Other options to solve this include:
- A separate class for each "variant", i.e.:
Downside here obviously is that it's partially duplicated code.data class Wrapper<T : String>(val wrapped: T) data class ListWrapper<T : List<String>>(val wrapped: T)
- Removing the upper bound, and using an
init
block to do an instance type check. Downside here is that the check moves to runtime.
Edit: I'm aware of multiple upper bounds using the where
keyword, however, that causes a limitation on accepted types which comply to both upper bounds (hence, it's a AND
construct)