I have the following object (for testing only):
{
type: 'custom',
source: (): number[] => { return [1,2,3,4] },
filters: [
{
text: 'Is in one of',
value: 'iiof',
action: (v: MainType, k: number[]) => true
},
{
text: 'Is not in one of',
value: '!iiof',
action: (v: MainType, k: number[]) => true
}
]
}
And I'm trying to build the types, so that the second parameter of any filter.action
function, will be the return type of source
. I can use any
, but would prefer to have this typed if possible.
My current types are the following:
export type FilterCustomImpl<T, K> = {
text: string;
value: string;
action: (v: T, s: K[]) => boolean;
};
export type FilterCustomSchemaField<T, K = any> = {
type: 'custom',
display?: string;
source: () => K[];
filters: FilterCustomImpl<T, K>[]
};
export type FilterSchemaField<T> =
FilterEnumSchemaField |
FilterNumericSchemaField |
FilterStringSchemaField |
FilterCustomSchemaField<T>;
export type FilterSchemaFields<T> = { [index: string]: FilterSchemaField<T> };
export type FilterSchema<T> = {
defaultKey: string;
fields: FilterSchemaFields<T>
};
So the parent FilterSchema
could have an infinite number of FilterCustomSchemaField
s with different K
types.
Currently when building the filter schema I can get around it by specifying the type on the field itself, so
{
type: 'custom',
source: (): number[] => { return [1,2,3,4] },
filters: [
{
text: 'Is in one of',
value: 'iiof',
action: (v: MainType, k: number[]) => true
},
{
text: 'Is not in one of',
value: '!iiof',
action: (v: MainType, k: number[]) => true
}
]
} as FilterCustomSchemaField<MainType, number>
But it's not a great approach because it obviously requires extra typing, and has to rewrite the main T
type each time.
It would be ideal if I could infer the K
type from the return type of the source
function, but I'm not sure that's possible.