SvelteStack / svelte-query

Performant and powerful remote data synchronization for Svelte
https://sveltequery.vercel.app
MIT License
813 stars 31 forks source link

feat(queries): infer types correctly when using useQueries #56

Closed SomaticIT closed 2 years ago

SomaticIT commented 2 years ago

Hi,

Description

This PR improve the behavior of the useQueries function.

  1. It allows typescript to automatically infer types from arguments
  2. It allows to specify manually the generic types of arguments

Automatic inference

const queryFn = () => "hello";
const queryFn2 = async () => "world";
const queryFn3 = async () => true;

// single type list detection
const singleTypeQueriesStore = useQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
]);
$: singleTypeData = $singleTypeQueriesStore.map(q => q.data); // singleTypeData is string[]

// multi-type list detection
const multiTypeQueriesStore = useQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
  { queryKey: 'myQuery3', queryFn: queryFn3 },
]);
$: multiTypeData = $multiTypeQueriesStore.map(q => q.data); // multiTypeData is (string | boolean)[]

// readonly tupple list detection
const tuppleQueriesStore = useQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
  { queryKey: 'myQuery3', queryFn: queryFn3 },
] as const);
$: tuppleData0 = $tuppleQueriesStore[0].data // tuppleData0 is string
$: tuppleData1 = $tuppleQueriesStore[1].data // tuppleData1 is string
$: tuppleData2 = $tuppleQueriesStore[2].data // tuppleData2 is boolean

Manual type selection

const queryFn = () => "hello";
const queryFn2 = async () => "world";
const queryFn3 = async () => true;

useQueries<string>([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
]);
// OK

useQueries<string>([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
  { queryKey: 'myQuery3', queryFn: queryFn3 },
]);
// Error

const emptyQuery = useQueries<string>([]);
// OK

const stringQuery = useQueries<string>([]);
stringQuery.setQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
]);
// OK

const stringQuery2 = useQueries<string>([]);
stringQuery2.setQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
  { queryKey: 'myQuery3', queryFn: queryFn3 },
]);
// Error

const mixedQuery = useQueries<string | boolean>([]);
mixedQuery.setQueries([
  { queryKey: 'myQuery', queryFn },
  { queryKey: 'myQuery2', queryFn: queryFn2 },
  { queryKey: 'myQuery3', queryFn: queryFn3 },
]);
// OK
SomaticIT commented 2 years ago

@amen-souissi, any news on this?