Skip to content

Schema definition circular references #3472

Closed

Description

@EmileSpecs

Hi

Please see sinclairzx81/typebox#844 for reference.

The solution offered unfortunately won't work in the context of feathers since none of the other functions like the TReference type produced for schema.

For example getValidator wants schema:
schema: TObject<TProperties> | TIntersect<TObject<TProperties>[]> | TUnion<TObject<TProperties>[]>

Is there any other suggested way of defining references to other schemas that reference each other that will work?

Reference to my definitions as mentioned in the post above:

// NOTE: these schemas are defined in different files and are displayed here as is for reference, thus I'm not getting errors like:
// Block-scoped variable 'accountSchema' used before its declaration.ts

const userSchema = Type.Object(
  {
    id: Type.String({ format: 'uuid' }),
    email: Type.String({ format: 'email' }),
    account: Type.Ref(accountSchema)
  },
  { $id: 'User', additionalProperties: false }
)

const accountSchema = Type.Object(
  {
    id: Type.String({ format: 'uuid' }),
    name: Type.String(),
    users: Type.Array(Type.Ref(userSchema)),
    locations: Type.Array(Type.Ref(locationSchema))
  },
  { $id: 'Account', additionalProperties: false }
)

The provided solution that does not solve the issue for me in feathers:

const userSchemaBuilder = <T extends TSchema>(reference: T) =>
  Type.Object({
    id: Type.String({ format: "uuid" }),
    email: Type.String({ format: "email" }),
    account: Type.Optional(reference),
  });

const accountSchemaBuilder = <T extends TSchema>(reference: T) =>
  Type.Object({
    id: Type.String({ format: "uuid" }),
    name: Type.String(),
    users: Type.Optional(Type.Array(reference)),
  });

const userSchema = Type.Recursive((This) =>
  userSchemaBuilder(accountSchemaBuilder(This))
);
const accountSchema = Type.Recursive((This) =>
  accountSchemaBuilder(userSchemaBuilder(This))
);
type User = Static<typeof userSchema>;
type Account = Static<typeof accountSchema>;

Would appreciate some help on how to make this work!

Activity

  1. EmileSpecs commented on Apr 23, 2024

    @EmileSpecs
    Author

    It seems to me like the most simple solution here is just to use JSON Schema instead, as it doesn't give any errors when doing the same circular relations.

    Any opinions, as I know TypeBox is the preferred option?
    Doesn't TypeBox just compile to JSON Schema anyway?

  2. locked and limited conversation to collaborators on Apr 23, 2024
  3. converted this issue into a discussion #3473 on Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions