I've got a third-party service that exposes a reified extension function. I would like to wrap this service into an interface-implementation pair for easier testing and encapsulation reason.
The problem is that I can't use this function in my app, because compiler tells me that:
Cannot use 'T' as reified type parameter. Use a class instead.
The structure is like following:
interface ThirdPartyService
inline fun <reified T> ThirdPartyService.execute(): T
interface Wrapper {
fun <T> execute(): T
}
class WrapperImpl(private val thirdPartyService: ThirdPartyService) : Wrapper {
override fun <T> execute(): T =
thirdPartyService.execute()
}
In this case calling thirdPartyService.execute()
causes a compiler issue I mentioned above.
Is there any way to overcome this issue? What does this Use a class instead.
actually means?
When you mark a type as reified, you're allowing it to be used explicitly in the function in places that it would normally be erased.
However the type
T
in yourWrapper.execute
function here is not reified which means that it will be erased at runtime and therefore unable to be 'passed' to theThirdPartyService.execute
function.You can read more about reified types here.
In essence, the whole point of a function with a reified type is that it can use the type at runtime. So calling it without a concrete type doesn't make any sense and due to type erasure, a non-reified
T
is not a concrete type.