Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 16, 2021. It is now read-only.
This repository was archived by the owner on Feb 16, 2021. It is now read-only.

Dealing with circular dependencies #332

@ArmorDarks

Description

@ArmorDarks

Version

2.4.0

Case

When defining model it isn't unusual to have a recursive structure, where one type circularly depends on another type.

Consider this:

Each Entity requires to have information about Place, where it belongs. But each Place is an Entity.

Thus, we have a circular dependency:

// entity.js

import Place from './place'

export const Entity = t.interface({
  place: Place
})
// place.js

import Entity from './entity'

export const Place = Entity.extend({})

Seems like there is no way to express such a relationship with tcomb, and current tcomb tooling makes it impossible to workaround.

Thoughts

Issue isn't related to the tcomb itself and rather a technical limitation of current modules implementation, but I found myself struggling to work around that issue with tcomb tools.

The root of the issue is that all tcomb declarations are "eager". They evaluated as soon as module loaded, and because another module isn't resolved yet either place.js will complain that it can't extend undefined (Entity which isn't loaded yet), or entity.js will complain that its interface declaration is faulty (because Place ends up undefined).

So, it feels like there should be a way to make type evaluation "lazy" — to force it to evaluate when used (and by that time in most case all variables should resolve), and not when declared. However, it means that meta information won't be available statically on type...

t.declare('Type') and Type.define doesn't help here much too, since it will be in same way eagerly evaluated and end up with broken types. Or maybe I'm missing obvious way how it helps in such situations?

I think maybe it could help if define could accept a function rather than a type definition.

However, to be honest, I wasn't able to come up with a good solution yet. Maybe someone knows the solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions