Properly typing Prismic Content Relationships

118 views Asked by At

I am trying to build a mega menu for a my header but am running into a type error and was wondering if anyone had run into this and how you solved it? I am importing the generated types from @/prismicio-types.

My client query looks like:

export default async function getHeaderSettings(
  client: Client<AllDocumentTypes>
): Promise<HeaderDocument<string>> {
  return client.getSingle('header', {
    graphQuery: `
          {
              header {
                  logo
                  menu {
                      label
                      is_link
                      link
                      submenu {
                          cta_image
                          menu {
                              item {
                                  ...itemFields
                              }
                          }
                      }
                  }
              }
          }
      `,
  });
}

Which is called and the appropriate data is passed into the header:

interface IHeader {
  data: Simplify<HeaderDocumentData>;
}

However when I try to access the data in the submenu I receive the following:

Property 'data' does not exist on type 'ContentRelationshipField<"header_submenu">'.
  Property 'data' does not exist on type 'EmptyLinkField<"Document">'.
const formatHeaderData = (data: Simplify<HeaderDocumentData>) => {
  const { menu, logo } = data;

  const formattedMenu = menu.length
    ? menu.map((item) => {
        return {
          label: item.label,
          is_link: item.is_link,
          link: item.link,
          submenu: {
            cta_image: item.submenu.data.cta_image,
            menu: item.submenu.data.menu.map((subMenuItem) => {
              return {
                menu_label: subMenuItem.item.data.menu_label,
                menu: subMenuItem.item.data.menu,
              };
            }),
          },
        };
      })
    : [];
  
  return {
    logo,
    menu: formattedMenu,
  };
};
1

There are 1 answers

0
Liam On

Your HeaderDocument type doesn't automatically contain the types for the content relationship fields. The best solution I've found to this is to embellish the return type of the getHeaderSettings function.

An example for one level of nesting (you will have to add the further levels):

import type { Content } from '@prismicio/client';

type HeaderWithMenuDocument =
  Content.HeaderDocument & {
    data: {
      menu: Content.MenuDocument;
    };
  };

then you can change the return type of your function

export default async function getHeaderSettings(
  client: Client<AllDocumentTypes>
): Promise<HeaderWithMenuDocument>