I have this sealed class PictureEvent
:
sealed class PictureEvent {
data class PictureCreated(val pictureId: String, val url: String) : PictureE
The contract works fine, however if you take a look at the first
method signature, you should be able to understand what is happening and why the found object isn't autocast:
public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T
The return type of the first
method is just the same as that defined for all elements in the Iterable
instance, PictureEvent
in your case, and no autocasting inside the predicate can unfortunately change that.
Instead of contracts, for example, you can filter your list by the desired class type first, and then take the first element:
val creationEvent = events
.filterIsInstance(PictureEvent.PictureCreated::class.java)
.first()
or create your own extension similar to first
:
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
val first = first { it is R }
return first as R
}
// or wrapping filterIsInstance
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
return filterIsInstance(R::class.java).first()
}
val creationEvent = events.firstOfInstance<PictureEvent.PictureCreated>()