Closed utterances-bot closed 2 years ago
That's really good! Thanks!
Thanks!
In the explicit-id-check
wouldn't TypeScript complain about it possibly not returning a Promise<Group>
but a Promise<Error>
or smth like that?
@Maadtin no, you only specific the type of resolved promises. Rejected promises don’t really have a type - you can reject with or throw anything.
Very useful article! Thanks a lot! Keep up the great work on this blog!
I was able to set the typing for the page parameter as follows:
type PageParam = MyData['nextPageUri']
export function useMyData() {
const server = useServer()
return useInfiniteQuery<MyData>(
keys.all,
({ pageParam: nextPageUri }: QueryFunctionContext<QueryKey, PageParam>) =>
fetchMyData(nextPageUri),
{
getNextPageParam: page => page.nextPageUri,
}
)
async function fetchMyData(nextPageUri: string | undefined) {
await server.get<MyData>(
nextPageUri ?? '/my_data'
)
}
}
@phatmann cool, I'm actually doing something similar right now :)
you can actually use generics to state axios return type
const {data} = axios.get<Type>(url)
// data is Type
Thank you so much for the blogposts, it has been an absolute blast reading all of them. However, I do need some help with typing useQueries
. I've been leveraging the query function context and it's been fantastic with single useQueries
.
However, when dealing with multiple queries in useQueries
array, I've been type assertion errors but I can't seem to figure out why. I'm definitely on typescript 4 and using the latest react-query packages that implement the recent updates to useQueries
types
an example would be
const queries = useQueries([
{
queryKey: dashboardQueryKeys.keyNumbers({ startDateTime: new Date() }),
queryFn: fetchDashboardAssetsSummary
}
])
The error always seems to suggest the context function is not inferring the correct types i.e Type 'QueryFunctionContext<QueryKey, any>' is not assignable to type 'QueryFunctionContext<readonly ...
@AndrewThian can you spawn a quick typescript playground or codesandbox that shows the typing issues with useQueries you have been facing? I have to admit, the typings for useQueries are a beast and I frequently need to reach for help from the original author. Maybe there is a real issue with them...
Thank you for replying at such a quick notice :) you're an absolute gem haha
I've attached a sandbox that sorta replicates the issues with typescript: sandbox
The offending type assertion is in the
const usePokemons = () => {
return useQueries([
{
queryKey: queryKeys.pagination({ limit: 100, offset: 200 }),
queryFn: fetchPokemon
}
]);
};
Looking forward to your expertise! Thank you once again
thank you @AndrewThian . It seems to be an issue. The inferred context is just: QueryFunctionContext<QueryKey, any>
. Can you open an issue in RQ with that reproduction, and I'll see what I (or someone else) can do :)
With TypeScript 4.6, the destructured example works thanks to control flow analysis for destructured discriminated unions.
const { data, isSuccess } = useGroups()
if (isSuccess) {
// ✅ data is narrowed to `Group[]` here
}
@dd-jonas yes, I'm aware and I plan on updating the blogpost. This is an amazing feat by the typescript team :)
Thank you for such an in-depth guide on using TypeScript with react-query
!
I would like to implement a useGroups
hook that takes an optional options
argument like so:
function useGroups(options?: unknown) {
return useQuery('groups', fetchGroups, options)
}
Is it possible to let TypeScript infer the type of options
?
Thank you again for sharing your knowledge!
Hey!
Please ignore my previous comment :P
The main issue I had with using useQuery
directly was that I felt the need to specify arguments as part of the queryKey
and the queryFn
. I saw myself writing the same object over and over again, which I wanted to avoid.
After reading your post on query keys, I realized there was a much easier way. Thank you so much!
Hi, I've just stumbled across your blog post and that got me thinking about something I've been stuck with recently, namely dehydration with SSR frameworks like NextJS.
I followed their examples for Next, but when I wanted to extract the data returned by DehydratedState, it gave me this:
function ArticleDetailPage({ dehydratedState }: PageProps): JSX.Element {
return (
<div>
{/* Some default Next page stuff */}
<Blog article={**dehydratedState.queries[0].state.data**.data[0] as Article} />
{/* ^ Object is of type 'unknown'. */}
</div>
);
}
I have getStaticProps setup like so:
export const getStaticProps: GetStaticProps<Props, Params> = async (context) => {
const { params } = context;
const slug = params?.slug ?? '';
const queryClient = new QueryClient();
await queryClient.prefetchQuery<StrapiAPIResponse | APIError, Oops, StrapiAPIResponse | APIError, QueryKey>(
'article-detail.get-article-detail',
async () => {
const response = await getArticleBySlug(slug);
return response;
},
);
return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
};
Is there any way to tell ArticleDetailPage what the fetched data type from react query is?
@earthnoob the recommended approach is to pass the dehydratedState to the Hydrate component provided by React query. That will fill the cache so that you can access it with useQuery.
awesome !
how to set type with useMutation()'s return mutation.mutate( {name, email, password} ) gives me error saying Argument of type '{ name: string; email: string; password: string; }' is not assignable to parameter of type 'void' i am perplexed
@imbishalgiri mutation.mutate
arguments map to the function you pass to useMutation
. I guess your function was without any arguments (i.e useMutation(() => doSomeMutation)
) while it should be useMutation({name, email, password})
@imbishalgiri it depends on the type of the mutationFunction (the first parameter to useMutation
). Given:
const { mutate } = useMutation(
(params: { name: string; email: string; password: string}) => someMutation(params)
)
you should be able to all it like:
mutate({ name, email, password })
thank you so much for your response. It worked!! and your response time was blazing fast but why am i not being able to destructure error
i mean after i do this
const { mutate, error } = useMutation((newUser: User) => {
return signup(newUser)
})
it gives me error line below error
if (error?.response?.data?.field === 'email') {
setError('email', {
type: 'custom',
message: error?.response?.data?.message,
})
}
My guess is because error is of type unknown, so you can't just access .response
, not even with optional chaining. I think I have this covered in the blog post :)
already tried instanceOf but typescript still yelling at me ... looks like i should deep dive into typescript
thank you for your help tho
React Query and TypeScript | TkDodo's blog
Combine two of the most powerful tools for React Apps to produce great user experience, developer experience and type safety.
https://tkdodo.eu/blog/react-query-and-type-script?utterances=b435597b2a9c58fa332c2615jllrscOW14fVS1v60n0O1dygX%2BCA7p%2BksVnlREfguN5WhmqBgs9LK8RdwuzgW20LtZbI8E96p4qHq2%2BISvhgyJUYr2Hqh0c5cae1SdnJEJBnM7BFNnQjLkT1bfQ%3D