Avoiding circular dependencies

I have 2 classes like so.

export class Risk {
  ... other properties

  mitigations?: Mitigation[] = [];
}

and

export class Mitigation {
  ... other properties

  risks?: Risk[] = [];
}

I understand we should never do this, as this is circular dependency. The problem is, this is the reality. We’re using neo4j, and can get back Risk with Mitigations, or a Mitigation with Risks.

How do I approach this case?

>Solution :

You can use interfaces instead of a class. Interfaces don’t have implementation details, so there’s no risk of creating a circular dependency between two interfaces:

export interface IRisk {
  // other properties
  mitigations?: IMitigation[]
}

export interface IMitigation {
  // other properties
  risks?: IRisk[]
}

Then, in your implementation files (e.g. risk.ts and mitigation.ts), you can implement the interfaces like this:

// risk.ts
import { IRisk, IMitigation } from './interfaces'

export class Risk implements IRisk {
  // implementation details

  mitigations?: IMitigation[] = []
}

// mitigation.ts
import { IRisk, IMitigation } from './interfaces'

export class Mitigation implements IMitigation {
  // implementation details

  risks?: IRisk[] = []
}

Leave a Reply