1

Usually when I create a TypeScript application I follow an OOP + immutable data philosophy.

So let's suppose I have two classes with mutual reference, class A and class B.

class A {
    public readonly item: B;

    public constructor (item: B) {
        this.item = item;
    }
}

class B {
    public readonly item: A;

    public constructor (item: A) {
        this.item = item;
    }
}

Now it's impossible to create instance of class A, since class B is required in constructor to achieve immutability, and class B requires instance of class A.

It's required to create first an instance of class A and B with item property set to undefined and then respectively assign the references after class instantiation. But this solution will break immutability since it will allow users to overwrite the item property.

Any proposed solution?

1
  • 3
    I think the only way to immutably "tie the knot" is to defer evaluation, which in JS can't happen unless you replace a value with a function that returns a value. Maybe like this. Does that meet your needs? (Edit: looks like ABOS's answer says exactly this) Commented Jan 16, 2022 at 0:49

1 Answer 1

3

One way is use getter to achieve lazy evaluation,

class A {
  private readonly _item: () => B;
  public get item(): B {
    return this._item();
  }

  public constructor(_item: () => B) {
    this._item = _item;
  }
}

class B {
  public readonly _item: () => A;
  public get item(): A {
    return this._item();
  }
  public constructor(_item: () => A) {
    this._item = _item;
  }
}

const a: A = new A(() => b);
const b: B = new B(() => a);

console.log(a.item === b); // true
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.