type FooFilter<T> = { type: 'Foo', foo: T }
type BarFilter<T> = { type: 'Bar', bar: T }
type Filter = FooFilter<unknown> | BarFilter<unknown>
type FilterShapeBase = [string, Filter][]
type ValueOf<F extends Filter> =
F extends FooFilter<infer T> ? T
: F extends BarFilter<infer T> ? T
: never
type FilterValues<FilterShape extends FilterShapeBase> = FilterShape extends Array<infer U>
? U extends [infer K, infer F]
? K extends string
? F extends Filter
? { [Key in K]: ValueOf<F> }
: never
: never
: never
: never
function f<FilterShape extends FilterShapeBase>(filters: FilterShape): FilterValues<FilterShape> {
const tuples = filters.map(([key, filter]) => filter.type === 'Foo' ? [key, filter.foo] : [key, filter.bar])
return Object.fromEntries(tuples)
}
/*
HOW TO CONFIGURE THE FILTER FilterShape:
type FilterShape = [
['foo_in', StringSearchFilter],
['bar_equals', EnumSelectOneFilter<MyEnum>]
]
const filters = [
['foo_in', { ... }],
['bar_equals', { ... }],
]
*/