I am trying to use the useQueryLoader
and usePreloadedQuery
hooks from react-relay
along with typescript and I am getting the following error. The error is specific to Typescript
because when I change the file type to jsx
the code works as expected.
TypeScript error in /src/components/places/PlaceListTest.tsx(13,30):
Type 'PreloadedQuery<OperationType, Record<string, unknown>>' is not assignable to type 'PreloadedQuery<PlacesListQuery, Record<string, unknown>>'.
Type 'OperationType' is not assignable to type 'PlacesListQuery'.
Types of property 'response' are incompatible.
Type 'unknown' is not assignable to type 'PlacesListQueryResponse'. TS2322
11 | }, [loadPlacesListQuery]);
12 | if(!!queryRef) {
> 13 | return <PlacesCardsList queryRef={queryRef}/>;
| ^
14 | } else {
15 | return "Loading...";
16 | }
Overall I am querying a list of places and displaying it as a grid of cards. The parent component file is PlacesListTest.tsx
with the following code. This is wrapped within the Suspense
block (not shown).
import React, { useEffect } from 'react';
import { useQueryLoader } from 'react-relay/hooks';
import { placesListQuery } from '../../queries/PlacesListQuery'
import { PlacesCardsList } from'./PlacesCardsList'
export const PlacesListTest = () => {
const [queryRef, loadPlacesListQuery] = useQueryLoader(placesListQuery);
useEffect(() => {
loadPlacesListQuery({});
}, [loadPlacesListQuery]);
if(!!queryRef) {
return <PlacesCardsList queryRef={queryRef}/>;
} else {
return "Loading...";
}
};
The code for PlacesCardsList.tsx
is:
import { usePreloadedQuery, PreloadedQuery } from 'react-relay/hooks';
import { Grid } from '@mui/material';
import { PlaceCard } from './PlaceCard';
import { NewPlaceButton } from './NewPlaceButton';
import type { PlacesListQuery } from '../../queries/__generated__/PlacesListQuery.graphql';
import { placesListQuery, PlacesListQueryProps } from '../../queries/PlacesListQuery'
export const PlacesCardsList = ({queryRef} : PlacesListQueryProps) => {
const data = usePreloadedQuery<PlacesListQuery>(placesListQuery, queryRef);
const places = data.places!;
return (
<div>
<NewPlaceButton/>
<Grid container marginLeft={5}>
{places!.map(place => (
<PlaceCard key={place!.id} place={place!}/>
))}
</Grid>
</div>
);
};
This is the PlacesListQuery.tsx
file
import graphql from 'babel-plugin-relay/macro';
import { PreloadedQuery } from 'react-relay/hooks';
import type { PlacesListQuery } from './__generated__/PlacesListQuery.graphql';
export const placesListQuery = graphql`
query PlacesListQuery {
places {
id
name
}
}
`
export type PlacesListQueryProps = {
queryRef: PreloadedQuery<PlacesListQuery>;
};
The type compatibility issue occurs in the queryRef
.
Also including the generated PlacesListQuery.graphql.ts
file below to show the response
type.
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from "relay-runtime";
export type PlacesListQueryVariables = {};
export type PlacesListQueryResponse = {
readonly places: ReadonlyArray<{
readonly id: string;
readonly name: string;
} | null> | null;
};
export type PlacesListQuery = {
readonly response: PlacesListQueryResponse;
readonly variables: PlacesListQueryVariables;
};
/*
query PlacesListQuery {
places {
id
name
}
}
*/
const node: ConcreteRequest = (function(){
var v0 = [
{
"alias": null,
"args": null,
"concreteType": "Place",
"kind": "LinkedField",
"name": "places",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "PlacesListQuery",
"selections": (v0/*: any*/),
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [],
"kind": "Operation",
"name": "PlacesListQuery",
"selections": (v0/*: any*/)
},
"params": {
"cacheID": "a18c05f26be453a1db0fb41cac930a84",
"id": null,
"metadata": {},
"name": "PlacesListQuery",
"operationKind": "query",
"text": "query PlacesListQuery {\n places {\n id\n name\n }\n}\n"
}
};
})();
(node as any).hash = 'a22e830ef7ff5fe90978f453f4adc02d';
export default node;
How do I setup the queryRef
such that the response
type is not unknown
? Any help would be appreciated!