Cast class to data class when using generics

Since data class hierarchy is not available, a workaround is to override non-data class hierarchy attributes above the data class, as per the example below:

abstract class AbstractA {
    abstract val a: String
}

abstract class AbstractB : AbstractA() {
    abstract val b: Int
}

data class DataC(
    override val a: String,
    val c: Long
) : AbstractA()

data class DataD(
    override val a: String,
    override val b: Int,
    val d: Long
) : AbstractB()

Now, suppose there are several distinct data classes in this small hierarchy. Some deriving from abstract class AbstractA and some from class AbstractB. Suppose I have simple functions, like the ones below, where I do not get the data classes as input parameters but the hierarchy classes (AbstractA and AbstractB). Rationale is that I want those functions to work for all data classes, as they change attributes defined in the abstract classes and overridden in the data classes. Please note I want to define common attributes for data classes, that’s why the hierarchy, AND I also want to maintain immutability in the data classes and use the built in copy function.

fun <T : AbstractA> changeA(item: T): T {
    return item.copy(a = "Hey") // compiler does not know item is a data class
}

fun <T : AbstractB> changeB(item: T) : T {
    return item.copy(a = "Hou", b = 10) // compiler does not know item is a data class
}

A mechanism to check if an object’s class is a data class, but what about casting it to a data class? I mean, this is not actually a cast, but making an object of a generic type to assume the role of a data class if indeed it is a data class. Something along the lines of:

fun <T : AbstractB> changeB(item: T) : T {
    require(item::class.isData)
    return (item as Data).copy(a = "Hou", b = 10)
}