Union types

This discussion has been going on a long time and is quite lengthy so my use case may already be well represented, especially by JSON-specific use cases.

I’m writing an application that consumes an XML-RPC API, and the XML-RPC spec prescribes a set of allowable types similar to JSON: int, string, double, boolean, array, struct, and null.

Right now I have these represented as a pile of sealed types that looks more-or-less like this (left out @Serializable and @JvmInline annotations where applicable for the sake of brevity):

sealed interface ValueType
sealed interface PrimitiveType : ValueType
sealed interface CompositeType : ValueType

value class StringType(val value: String) : PrimitiveType
value class IntType(val value: Int) : PrimitiveType
value class BooleanType private constructor(val value: Int) : PrimitiveType
value class DoubleType(val value: Double) : PrimitiveType
object NullType : PrimitiveType

data class ArrayType(val data: List<ValueType>) : CompositeType
data class StructType(val members: Map<String, ValueType>) : CompositeType

Right now I’m trying to add an extra layer on top of StructType to help unboxing members so application code can work directly with builtin types instead of ValueType. Unfortunately the API so far is very boilerplate-y with a set of functions like:

fun StructType.intOrNull(key: String): Int? {
    require(key in members) { "No member named $key" }
    return members[key]
}
fun StructType.doubleOrNull(key: String): Double? ...
fun StructType.booleanOrNull(key: String): Boolean? ...
fun StructType.stringOrNull(key: String): String? ...

where each on is identitcal except the return type.

If instead I was able to do something like this (which I think is some combination of many other suggestions in this thread):

typealias XmlRpcValue = Int? | Double? | Boolean? | String? | List<ValueType>? | Map<String, ValueType>?

it would not only make my “unboxing” API easier, but also (probably) allow me to drop my pile of sealed types all together and work directly with builtin types.