I want to write an extension method on a generic type T, where the matched type constrains a method parameter.
I want this to compile:
\"Hello\".thin
As mentioned by @Alexander Udalov it's not possible to do directly but there's a workaround where you define the extension method on another type like so:
data class Wrapper(val value: T)
val T.ext: Wrapper get() = Wrapper(this)
fun Wrapper.thing(p: T) {
println("value = $value, param = $p")
}
With the above the following compiles:
"abc".ext.thing("A")
but the next fails
"abc".ext.thing(2)
with:
Kotlin: Type inference failed: Cannot infer type parameter T in fun Wrapper.thing(p: T): Unit
None of the following substitutions
receiver: Wrapper arguments: (String)
receiver: Wrapper arguments: (Int)
can be applied to
receiver: Wrapper arguments: (Int)
As suggested by @hotkey it seems that it should be possible to avoid the need for explicit Wrapper type with the following extension property:
val T.thing: (T) -> Any? get() = { println("extension body") }
And then use it as "abc".thing("A") but it also fails. Surprisingly the following does compile "abc".thing.invoke("A")