#Recursive 'extend' workaround

1 messages · Page 1 of 1 (latest)

bold lodge
#

What about?

declare module '@placeholder/server-base' {
    interface Player extends RepEntity<PlayerMp> {}
}

interface PlayerExtension extends Player {}
#

If they are supposed to be the same thing, then just change one of them and let the other be the same.

#

Then put whatever things in PlayerExtension also inside Player.

#

So your entire PlayerExtension is just empty.

#

But I don't know why PlayerExtension even needs to exist at all, if everything is just a Player.

bold lodge
#

Then PlayerExtension should extends Player, while Player should not extends PlayerExtension.

#

I still don't see why they need to extend each other.

bold lodge
#

Your whole issue is just that they extend each other and is causing circular reference.

#

Sorry I have no clue what you are trying to do, you said one should be an extension of the other, then naturally they won't be extending each other, then it wouldn't have the circular reference issue.

#

Is Player a class? How are you extending it into PlayerExtension?

#

Then PlayerExtension is just an implementation detail, since you already use ApplyMixin to completely merge both Player and PlayerExtension into each other.

#

All you need to do is just:

declare module '@placeholder/server-base' {
    interface Player extends RepEntity<PlayerMp>, PlayerExtension {}
}

class PlayerExtension {
    // ...
}

ApplyMixins(Player, [RepEntity<PlayerMp>, PlayerExtension])

And then juse use Player everywhere.

#

Ah I see, this is why it's kind of a bad API design.

#

The typically API design is to have the server would expose the Player, and the server constructor/configuration would take in a class, so you have something like:

import { Player } from '@placeholder/server-base'

export class ExtendedPlayer extends Player {
    // You have access to all Player members
}
import { createServer } from '@placeholder/server-base'
import { ExtendedPlayer } from './ExtendedPlayer'

const server = createServer(ExtendedPlayer)
#

And everywhere server uses/returns Player will now become an ExtendedPlayer instead.

bold lodge
#

😅

#

I'd still much prefer a proper API design like the above than hacks, but well if it works it works.

bold lodge
#

You can still use your AddMixin.

#

Well, I guess if you also need to access RepEntity<PlayerMp> inside the implementation of PlayerExtension then it wouldn't work.

#

But honestly this is just classic "multiple inheritance" issue.

#

Multiple inheritance is universally considered bad, C++ is like the few languages that have it.

#

Most mainstream languages, eg JS, TS, Java, C#, don't have multiple inheritance. Even newer languages, eg Go, Rust, don't have inheritance at all.