Home > Software design >  DSL, extending an interface method with a lambda with receiver as argument
DSL, extending an interface method with a lambda with receiver as argument

Time:10-02

I have the following interface with a function accepting a lambda with the same type receiver of the interface itself:

interface WebhookEventInterface<T> {

    operator fun invoke(block: WebhookEventInterface<T>.() -> Unit) {..}
}

Now I'd like to extend this interface with another one providing additional capabilities/features on top of the previous one, something like:

interface PushPullRequestFeatures<T> : WebhookEventInterface<T> {

    override operator fun invoke(block: PushPullRequestFeatures<T>.() -> Unit) {..}
}

Of course the compiler complains because there is a function signature clash in PushPullRequestFeatures with his super invoke method and override overrides nothing.

How can I override the invoke method of the super WebhookEventInterface in PushPullRequestFeatures while offering a receiver of the same type?

CodePudding user response:

In Kotlin, you can't (as far as I know) change the parameter types when overriding at all, so you can't change them in this particular way either.

What you can do is make the receiver type into another type parameter:

interface WebhookEventInterface<T, out W : WebhookEventInterface<T, W>> {
    operator fun invoke(block: W.() -> Unit) { ... }
}

interface PushPullRequestFeatures<T> : WebhookEventInterface<T, PushPullRequestFeatures<T>> {
    override operator fun invoke(block: PushPullRequestFeatures<T>.() -> Unit) { ... }
}

(If you don't override, the receiver type will be PushPullRequestFeatures<T> anyway because that's just what W is here.)

  • Related