I disagree with the “code design flaw”, this is a common pattern to keep componentized model when you deal with some parts of code (I see this a lot in Unity when creating componentized UI systems).
My recommendation @smellypotato is to have the properties as cc.Node, which can be assigned in the inspector, and during the onLoad function do a “getComponent” in these nodes and store the result in another variable
Hope I’m not sending you on a wild goose chase, and I haven’t tried this, but just thinking through the problem you may be able to crudely get around this:
Define properties as Nodes
Create interfaces from the classes you need
Call getComponent with a string instead of the type, cast to the interface.
So something like this:
In B.ts declare:
export interface InterfaceB extends B {}
In A.ts, do something like this
// Do NOT import B, just the interface
import { InterfaceB } from "./B"
@ccclass
export class A extends cc.Component {
@property (cc.Node)
nodeB: cc.Node = null;
public someMethod(): void {
let propB = A.getComponent("B") as InterfaceB;
}
}
You would do these for each of the classes that had a circular dependency (I suppose you technically only need to do this for one, since the last one creates the loop? I dunno …)
Like I said, I have not tried this, so hopefully I’m not sending you on a wild goose chase. I just know how frustrating these stupid TS circular dependencies can be and was hoping to possibly help out. If this doesn’t work, maybe it’ll help you on the path to figuring out something that does.