type Input = { [K in keyof Output]: { foo: () => Output[K] }; }; function convert(input: Input): Output { const keys = Object.keys(input) as (keyof Input)[]; return keys.reduce( (output, key) => ({ ...output, [key]: input[key].foo() }), {} as Output ); } const output = convert<{ a: number; b: string; c: boolean; }>({ a: { foo: () => 1 }, b: { foo: () => '!' }, c: { foo: () => true }, }); console.log(output); // = { a: 1, b: '!', c: true }