saiichihashimoto / sanity-typed-schema-builder

Build Sanity schemas declaratively and get typescript types of schema values for free!
https://saiichihashimoto.github.io/sanity-typed-schema-builder
MIT License
67 stars 5 forks source link

Cyclical references #206

Open ehwarren opened 1 year ago

ehwarren commented 1 year ago

I'm not too sure this is an issue with the code, however, with no examples I just cant seem to get this to work properly.

Example would be an object called "Button", which contains text and a reference to sanity document types

button.ts

import { s } from 'sanity-typed-schema-builder'
import Page from 'schemas/documents/page'

const Button = s.objectNamed({
  name: 'button',
  fields: [
    {
      name: 'text',
      title: 'Text',
      type: s.string(),
    },
    {
      name: 'link',
      title: 'Link',
      type: s.reference({ to: [Page] }),
    },
  ],
})

export default Button

Then we have a reference to this button within the page document as well

page.ts

import Button from 'schemas/objects/page`
const Page = s.document({
  name: 'page',
  title: 'Pages',
  icon: DocumentIcon,
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: s.string(),
    },
    {
      name: 'someButton',
      title: 'Button',
      type: Button.ref()
    },
  })

The Button is a named object because it is used in portable text blocks elsewhere aswell.

The only "solution" i could find right now was to hack the reference within the Button declaration as follows. This eliminates the need to reference the Page document, which is causing the cyclical reference.

const Button = s.objectNamed({
  name: 'button',
  fields: [
    {
      name: 'text',
      title: 'Text',
      type: s.string(),
    },
    {
      name: 'link',
      title: 'Link',
      /*@ts-ignore Importing page would give a cyclic reference*/
      type: s.reference({ to: [{ name: 'page' }] }),
    },
  ],
})

Is there any other way around this that I'm just missing?

saiichihashimoto commented 1 year ago

I'm going to leave this open since it's been brought up a few times #114 & #138. The long and short of it is that inferred recursive types isn't really possible. Somehow, the typescript loop has to be manually defined. Even the builder plan doesn't really seem to solve the problem.