If we interact with TS framework, which expect tha...
# javascript
u
If we interact with TS framework, which expect that TS classes is inherited with TS
extends
, we get defective inheritance (in short, it does not work). As workaround I do such thing:
Copy code
class Kotlin : TypeScript() {
    init {
        tslib.__extends(Kotlin::class.js, TypeScript::class.js)
    }
}
Can this be done somehow more elegantly / correctly? I think extending of TS class should be supported by Kotlin/JS. With annotation of external TS class or somehow else.
u
Hi! Can you please be more specific, that is 1) provide some snippet with exact code 2) tell what you expect this code should be doing 3) tell what actually happens
u
@[JB] Shagen sorry but I can't be more more specific. Because it's very complex framework, use-case is complex too. I am sure you will not deploy this whole environment to reproduce it. But I do not think that this problem is specific only for my case. Therefore, I simply point out the problem. TypeScript uses the
__extends
function to extend a class. And it is logical to assume that TypeScript code expects it to be called. I do not know how
__extends
works and what it does. You can see it here: https://www.typescriptlang.org/play/#src=class%20TypeScript%20%7B%20%7D%0D%0A%0D%0Aclass%20Kotlin%20extends%20TypeScript%20%7B%7D Or read something about it here: https://stackoverflow.com/questions/45954157/understanding-the-extends-function-generated-by-typescript
u
Just to clarify - are you trying to extend a class which was generated by TypeScript?
u
@[JB] Shagen yes. And this class should interact with other code generated by TypeScript. I assume that the problem is somehow related to the static properties in TypeSctipt (which are inheritable in TypeScript). Most likely the TS framework expects such static properties from the Kotlin/JS class (which was inherited from TS class)
u
I see - the thing is that Kotlin/JS is designed to have a seamless interop with javascript - so everything that is declared in TypeScript can, of course, be used in Kotlin (in case all relevant declarations are adopted). Any JavaScript class can be extended in Kotlin as well. However as you've already seen - there's no guarantee that typescript compiler is generating classic javascript classes - well, actually, it does not. Even if you'll come up with any workarounds keep in mind that there's absolutely no guarantee that this won't break for next versions of typescript. So, unfortunately all I can do in this particular case is to strongly recommend against of such approach and use composition instead of inheritance.
u
@[JB] Shagen Composition will not allow the TS framework to perceive my class as an appropriate component (I am forced to use inheritance)
u
To my knowledge Typescript was never designed in mind with the guarantee that you can inherit generated entities in first place. Subsequently Kotlin/JS was not designed to support this scenario either.
u
@[JB] Shagen Perhaps, I misunderstood you. But extending with TypeScript of the already generated JS class from TypeScript never caused any problems. Also with
ES6
target TypeScript don't generate
__extends
function. So looks like
__extends
function is just implement some
ES6
features.
a
@U75957 Seems you are right - we don't copy static properties, like TypeScript does. I don't think there is an elegant solution to this.
If you think this scenario should be supported, please create an issue.
How large is the API surface area in your case? Do you have to extend a lot of TypeScript classes?
u
@anton.bannykh yes, I have to extend a lot of TypeScript classes (and extend a lot of times each of them). Ok, of course I will create an issue and post a link here (a little bit later) Also my workaround is not correct, because
__extends
will be called for every instance (This is valid only for singleton
object
). I've tried to put this massive list of
__extends
calls to top of the app
main()
function, but it does not work.
a
Thanks! Also it seems that we'll have a similar problem with ES6.
@U75957 If the problem is with the statics, you could try copying them manually like this
js("Object").setPrototypeOf(B::class.js, A::class.js)
.
Calling
__extends
in the constructor will mess up the prototypal inheritance I think
I think having a massive list of `setPrototypeOf`'s should work.
Or you could have a dummy top-level property for each class, e.g.:
Copy code
class B: A()

val dummyB = js("Object").setPrototypeOf(B::class.js, A::class.js)
u
@anton.bannykh thank you. I've checked and looks like both workarounds you provide do the job. Will create the issue tomorrow (have no time today)
a
👍
u
a
Thanks 😃