-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Is your feature request related to a problem? Please describe.
Content from a content relationship field's document can be included in a query using the fetchLinks
or graphQuery
options. Typing those fields with TypeScript is difficult, however, requiring type assertions (as
) or manual type parameters (getByUID<...>
).
Describe the solution you'd like
A helper function could be provided that checks if a field is included in the query and automatically types the property. We can accomplish this using @prismicio/client
's Content
namespace.
Something like the following isFilledRelatedData
could be used:
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"],
TFieldID extends keyof DocumentData<TDocumentType>,
>(
linkField: LinkField,
documentType: TDocumentType,
fieldID: TFieldID,
): linkField is FilledContentRelationshipField & {
data: {
[P in keyof DocumentData<TDocumentType> as P extends TFieldID
? P
: never]: DocumentData<TDocumentType>[P];
};
} {
return (
isFilled.contentRelationship(linkField) &&
linkField.type === documentType &&
typeof linkField.data === "object" &&
linkField.data !== null &&
fieldID in linkField.data
);
}
isFilledRelatedData()
's name can be misleading since it doesn't actually check if the field is filled. Instead, it checks that the linked field was queried via fetchLinks
/graphQuery
.
We would probably refocus the helper into something like hasRelationshipField()
, which would still require you to check that the field was filled with isFilled()
.
if (
hasRelationshipField(item.brand, "brand", "title") &&
isFilled(item.brand)
) {
// ...
}
Describe alternatives you've considered
Project-specific runtime checkers can be written using isFilled
, but it is cumbersome to write and maintain.
See https://community.prismic.io/t/types-for-content-relationship-in-a-slice/12067/2 for an example.