lukemorales / query-key-factory

A library for creating typesafe standardized query keys, useful for cache management in @tanstack/query

Home Page:https://www.npmjs.com/package/@lukemorales/query-key-factory

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow typing the query type and Error when using useQuery

opened this issue · comments

Taking this from the example:

export const users = createQueryKeys('users', {
  list: () => ({
    queryKey: [],
    queryFn: () => api.findAll(),
  }),
});

export function useUserList() {
  return useQuery(users.list);
};

When doing:

export function useUserDetail(id: string) {
  return useQuery<User[], Error>(users.list);
};

you get:

"Type 'NonNullable<TQueryFnData> | never[]' is not assignable to type 'User[]'

I'm afraid I'm having trouble using either codesandbox or stackblitz on my computer, so I can't provide a repro here :(
I did consider providng a failing test, but you don't seem to test against useQuery directly in this repo according to the code search.

The query does work just fine though, but I want to be able to type the second param as Error

@jrobeson the issue is that once you pass generics manually to a function, Typescript stops inferring the values and what you're experiencing is Typescript complaining about QueryKey default value not matching the typed queryKey that comes from the package.

If you'd want to always have error typed as Error instead of unknown, I'm afraid there's no solution other than manually pass the 4 generic values:

export const users = createQueryKeys('users', {
  list: { // also note that in this case you need a direct object instead of a function since you don't have arguments
    queryKey: null,
    queryFn: queryFn: () => api.findAll(),
  },
});

export function useUserList() {
  return useQuery<User[], Error, User[], typeof users.list.queryKey>(users.list);
};

But I don't think that's worth the added complexity, and also, the roadmap to v5 indicates that they'll probably make error default to Error instead of unknown, so bear with them for a while and you should get the end result you want in the next few months

I've never had to do all 4 params before, so that's why I was confused. I'll probalby provide them in the meantime then. thanks

I've never had to do all 4 params before, so that's why I was confused. I'll probalby provide them in the meantime then. thanks

It's mostly because users.list.queryFn comes fully typed with the QueryFunction type already knowing the shape of QueryKey, so it conflicts with the generic QueryKey fallback present in useQuery

Perhaps making the type less strict there might be more useful? Let me sleep on that ideia