Shouldn't react-compiler generate query$data type with the " $data" prop too?
I'm confused why the generated types from query is missing the " $data" property. Like this:
export type NewProductReviewScreenInitialQuery$data = {
readonly product: {
readonly " $fragmentSpreads": FragmentRefs<"NewProductReviewScreen_ProductFragment">;
} | null | undefined;
readonly review: {
readonly " $fragmentSpreads": FragmentRefs<"NewProductReviewScreen_ReviewFragment">;
} | null | undefined;
};
The above was generated from a usePreloadedQuery like this
export const newProductReviewScreenInitialQuery = graphql`
query NewProductReviewScreenInitialQuery(
$reviewId: UUID!
$productId: UUID!
) {
product(id: $productId) {
...NewProductReviewScreen_ProductFragment
}
review(id: $reviewId) {
...NewProductReviewScreen_ReviewFragment
}
}
`;
const fragRef = usePreloadedQuery(
newProductReviewScreenInitialQuery,
queryRef
);
So the type for fragRef.product would be
{
readonly " $fragmentSpreads": FragmentRefs<"NewProductReviewScreen_ProductFragment">;
}
I think this is wrong.
The @types/react-relay/relay-hooks/useFragment.d.ts contains
export function useFragment<TKey extends KeyType>(
fragmentInput: GraphQLTaggedNode,
fragmentRef: TKey,
): KeyTypeData<TKey>;
and @types/react-relay/relay-hooks.helpers.td.ts contains
export type KeyType<TData = unknown> = Readonly<{
" $data"?: TData | undefined;
" $fragmentSpreads": FragmentType;
}>;
export type KeyTypeData<TKey extends KeyType<TData>, TData = unknown> = Required<TKey>[" $data"];
This is implying to me that the useFragment requires the fragRef.product to be generated with the corresponding " $data" property. Otherwise, I always have to explicitly provide the ...$key type in order to use useFragment:
const productProfileData = useFragment<NewProductReviewScreen_ProductFragment$key>(
graphql`
fragment NewProductReviewScreen_ProductFragment on Product {
ofVendor {
ofUser {
firstName
}
}
}
`,
fragRef.product
);
Without the <NewProductReviewScreen_ProductFragment$key> explicitly provided, the return value is unknown.
Versions:
@types/[email protected] @[email protected] @[email protected]
Are you observing that a type param is currently required for useFragment in TypeScript? If so, I believe that is expected, and a current limitation. If you have a concrete proposal for a way we could generate types which would avoid that, I'd be open to hearing it.
One approach is currently being explored in https://github.com/facebook/relay/issues/4884
Thanks for the explanation. I thought my configuration was wrong.
Hi @captbaritone, currently is there any technical difficulty for simply generating the type as
export type NewProductReviewScreenInitialQuery$data = {
readonly product: NewProductReviewScreen_ProductFragment$key | null | undefined;
};
instead of the current behavior of generating this:
export type NewProductReviewScreenInitialQuery$data = {
readonly product: {
readonly " $fragmentSpreads": FragmentRefs<"NewProductReviewScreen_ProductFragment">;
} | null | undefined;
};
?
The former seems that it will fit right into the KeyTypeData<TKey> type.
How would your example look if there were other fields being read off of product in addition to the fragment spread?