David Kubecka
08/12/2024, 9:37 AM// this is (basically) from WebTestClient
class RequestHeadersSpec<S : RequestHeadersSpec<S>> {
fun header(headerName: String, headerValue: String): RequestHeadersSpec<*> = this
}
// this is my extension
fun <S : RequestHeadersSpec<S>> S.customHeader(headerValue: String): RequestHeadersSpec<*> =
header("custom-header", headerValue)
fun main() {
val spec = RequestHeadersSpec()
spec.customHeader("value")
}
Basically I want the customHeader
extension to have the same receiver and output type as header
. I'm getting "receiver type mismatch" on the call site, however.
https://play.kotlinlang.org/#eyJ2ZXJzaW9uIjoiMi4wLjIwLVJDIiwicGxhdGZvcm0iOiJqYXZhIiwiYX[…]BlYygpXG4gICAgc3BlYy5jdXN0b21IZWFkZXIoXCJ2YWx1ZVwiKVxufSJ9Sam
08/12/2024, 9:47 AMapply
, and let Spring worry about the awkward generics
fun <T : RequestHeadersSpec<*>> T.customHeader(headerValue: String): T =
apply { header("custom-header", headerValue) }
David Kubecka
08/12/2024, 10:03 AMSam
08/12/2024, 10:05 AMfun <S : RequestHeadersSpec<out S>> S.customHeader(headerValue: String): RequestHeadersSpec<*> =
header("custom-header", headerValue)
But trying to make a 'self type' with generics is always a mess, and if you're already using extension functions, apply
is an easy way out.David Kubecka
08/12/2024, 10:53 AMapply
way works but I don't exactly understand how:
• first, you need to use wildcard base type RequestHeadersSpec<*>
• second, what exactly apply
brings to the game wrt types?David Kubecka
08/12/2024, 10:54 AMapply
we are completely ignoring the problematic typing of headers
and just returning the receiver type