You can utilize a syntax like this:
function a<T extends any[]>(...items: {
[K in keyof T]: T[K] & { func: (v: Omit<T[K], 'func'>) => void }
}) {}
A mapped type can be used to map over each element in items. T[K] always represents the current element, so we can use it to intersect itself with the function object.
// ok
a({
name: "",
func: (v: { name: string }) => {}
}, {
count: 0,
func: (v: { count: number }) => {}
})
// error
a({
name: 0,
func: (v: { name: string }) => {} /*
~~~~ Types of property 'name' are incompatible
*/
}, {
count: 0,
func: (v: { count: number }) => {}
})
For the implementation of the function, I would recommend to put all the complex generic stuff in an overload and to use a simpler signature for the implementing function.
function b<T extends any[]>(...items: {
[K in keyof T]: T[K] & { func: (v: Omit<T[K], 'func'>) => void }
}): void
function b(...items: ({ func: (arg: object) => void } & Record<string, any>)[]) {
for (const item of items) {
item.func({})
}
}
Playground
Whatin your case?Whatis a generic parameter