React Query with TypeScript - how to force the rule that the query key always needs to be an array

Viewed 190

I am new in TypeScript and we want to somehow "extend" the existing useQuery hook from react-query by the rule that the query key needs to be an array keys with 2 items at least. Something like

const { data } = useQuery<Data, Error>(["module_1", "fetchA"], fetchFn); // OK
const { data } = useQuery<Data, Error>("module_1", fetchFn); // there should be TS error because queryKey is not array
const { data } = useQuery<Data, Error>(["module_1"], fetchFn); // there should be TS error because array has only 1 item
  1. how to "extend" the useQuery hook
  2. how to add such a type in TS

Thank you in advance

1 Answers

You could write a more strict Data type like such:

type Data = [any, any, ...any[]];

This is a tuple telling the compiler Data should at least contain 2 elements and can contain "an infinity" more

Replace the any's with the actual type you need to use. This will result in errors when trying to use something else than an array of length < 2

const a: Data = [1];
// will raise a compiler error:
// Type '[number]' is not assignable to type '[any, any, ...any[]]'.
//  Source has 1 element(s) but target requires 2.

From what I gathered here https://react-query.tanstack.com/guides/query-keys queries base type is string | unknown[] so you can try to follow this typing closely with something like this:

type QueryTuple = [unknown, unknown, ...unknown[]];
// ...
const { data } = useQuery<QueryTuple, Error>(["module_1", "fetchA"], fetchFn);

or in your case, simply restrict it to the string type:

type QueryTuple = [string, string, ...string[]];
// ...
const { data } = useQuery<QueryTuple, Error>(["module_1", "fetchA"], fetchFn);
Related