is there some kind of magic type parameter that re...
# getting-started
b
is there some kind of magic type parameter that refers always to the current instance like Self? I'm in front of an api with an inherited updated method that always returns the same class as the current object:
Copy code
open class Model {
    fun update(): Model {
        // logic in here
        TODO()
    }
}

open class User: Model()

open class SpecialUser: User()
obviously User.update() should return a User and SpecialUser.update() a special user but I don't really see a way of having the type defs work other than overriding it with a more special one in each subtype PS: it's a JS API, just trying to figure out what the limits of Kotlin's type system are 🙂
🚫 1
r
you can do something like this:
Copy code
open class Model<out T: Model<T>> {
    fun update(): T {
        // logic in here
        TODO()
    }
}

open class User: Model<User>()

open class SpecialUser: Model<SpecialUser>()
b
SpecialUser needs to inherit User though
r
ah, missed that requirement 😅
b
yeah, typo first; it's the thing that really messes this all up
you basically need to pass up a concrete type through the chain while also not being allowed to have a type parameter
r
There’s a YouTrack issue for Self types you could vote on: https://youtrack.jetbrains.com/issue/KT-6494/Self-types
y
Well you could separate it into 2 methods:
Copy code
open class Model {
  fun doUpdate() {
    // logic in here
  }
}
fun <M: Model> M.update(): M = this.also { doUpdate() }
b
hm, that's nifty, basically using a generic function parameter instead of defining that on the method
however, I'm unsure if this exact solution would work for external js type definitions since I guess that both method signatures must be the same
and also only returns the current instance, not the new instance returned from the doUpdate() method
Copy code
fun <T : Model> T.typesafeUpdate(): T = update() as T
@Youssef Shoaib [MOD] thanks, I think this is good enough
y
Sure yeah as long as you're sure that
update
always returns the same type then this is fine. I wonder how this is implemented on the JS side? Prototype shenanigans?
b
@Youssef Shoaib [MOD]
Copy code
await this.constructor.update()
that one is a static method which uses this
there's a lot of weird stuff, like "here's a static method, but we bound the this to an instance"
y
Huh fun! Is the whole hierarchy in JS? If so then I guessed this'll likely be safe.
b
right 🙂
everyone told them to not do it since it couldn't be typed properly in TS
but they wanted something akin to Django models