I'm not too sure how to describe the issue I'm facing, but here's a concrete example :
I have this defineTable function that accepts a tanstack query option definiton, and I want to infer the data returned on the property results of this query.
import type { QueryKey, QueryOptions } from '@tanstack/vue-query';
export type Primitive = string | number | symbol;
export type GenericObject = Record<Primitive, unknown>;
type MaybePromise<T> = T | Promise<T>;
type QueryOption = QueryOptions<{ count: number; total: number; results: any[] }>;
type QueryData<QOpt extends QueryOption> = QOpt['queryFn'] extends () => MaybePromise<infer T>
? T extends { results: Array<infer U> }
? U
: never
: never;
export type FetchParams = {
sort: string;
page: number;
perPage: number;
};
export type DataListSchema<
Opts extends QueryOption,
Data extends QueryData<Opts>,
Query extends (params: FetchParams) => Opts = (params: FetchParams) => Opts,
> = {
query: Query;
data: Data;
};
function defineTable<Opts extends QueryOption, Data extends QueryData<Opts>>(
schema: DataListSchema<Opts, Data>,
) {}
This works fine, when I do this :
defineTable({
// NO PARAMS
query: () => ({
queryKey: ['table', 'data'],
queryFn: () =>
Promise.resolve({
count: 10,
total: 100,
results: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
],
}),
}),
// TYPE IS PROPERLY INFERRED
data: { id: 1, name: true },
});
But when I try to use the parameter of the query function, the inferred data type becomes "never"
defineTable({
// PARAMS IS USED
query: (params) => ({
queryKey: ['table', 'data', params],
queryFn: () =>
Promise.resolve({
count: 10,
total: 100,
results: [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
],
})
}),
// TYPE INFERRENCE LOST
data: { id: 1, name: true },
});