I’m not entirely sure if enforcing this type-check is possible. It might be, but I don’t know how to achieve it.
Since you’ll probably use a workaround anyway, here’s a much simpler approach you can try:
const construct = <R>(f1: () => R, f2: (x: R) => void) => ({
f1,
f2,
});
const result = construct(
() => 'string',
(x) => {}
// ^ x: string
);
If you prefer to declare as an object you can do so as well:
const construct = <R>(obj: { f1: () => R; f2: (x: R) => void }) => obj;
construct({
f1: () => true as const,
f2: (x) => {},
// ^ x: true
});