Iterating over graphQuery results for group fields with linked documents in TypeScript

When using the graphQuery with a document that has a group field that itself contains related documents, TypeScript throws an error: Property 'data' does not exist on type 'ContentRelationshipField<"procedure">'.

You can see also the attached screenshot.

How should I iterate over the fields so that I don't get any typescript error? I am using nextjs version 14.

The only way I found was the following, but it doesn't feel right...

 const procedures = homepage.data.procedures.map(
    ({ procedure }) => (procedure as unknown as ProcedureDocument).data
  );

Hi @tudor2004, thanks for asking!

When using Graph Query, we cannot exactly type the returned document according to your query yet (we're exploring ways to do so but it might not be feasible due to some limitations in TypeScript).

Moreover, content relationship fields may or may not be filled, that's why they are typed as such (in the above screenshot, you can see it's giving you the error based on the case when it's empty).

To work that around, you can write a type guard checking if the content relationship field is filled or not, and that it links to the correct document type (also fetching its data), allowing you to get proper typing. Here's an example:

// src/lib/isFilledRelatedData.ts

import {
  Content,
  FilledContentRelationshipField,
  LinkField,
  isFilled,
} from "@prismicio/client"

type DocumentData<TDocumentType extends Content.AllDocumentTypes["type"]> =
  Extract<Content.AllDocumentTypes, { type: TDocumentType }>["data"]

export function isFilledRelatedData<
  TDocumentType extends Content.AllDocumentTypes["type"],
>(
  linkField: LinkField,
  documentType: TDocumentType,
): linkField is FilledContentRelationshipField & {
  data: DocumentData<TDocumentType>
} {
  return (
    isFilled.contentRelationship(linkField) &&
    linkField.type === documentType &&
    typeof linkField.data === "object" &&
    linkField.data !== null
  )
}

This helper checks that a content relationship is filled and that it contains a document of type documentType. It then asserts its type as such. Feel free to adapt it to your needs!

It is inspired from this previous answer by Angelo here: Content relationship types within another content relationship in a Slice - #3 by angeloashmore which was checking the same for a single field.

Let us know if that answer your question, happy to help further :smiling_face: