I am working with a set of function factories that all have the same return types, each returning an operation (in this case, a CRUD operation). The return type of these operations is a Promise for simplicity.
My goal is to convert an object of function constructors into an object of functions returned by these constructors, while maintaining static typing. In other words:
{f1: (k: K) => (...) => Promise<...>, f2: (k: K) => (...) => Promise<...>}
should become
{f1: (...) => Promise<...>, f2: (...) => Promise<...>}
when a key K is applied.
For example:
type K = 'a' | 'b';
const makeGet = (k: K): (id: string): Promise<DbRecord<K>> => {...}
const makeSet = (k: K): (id: string, Partial<DbRecord<K>>): Promise<void> => {...}
const fs = {get: makeGet, set: makeSet} as const;
export const makeCrud = (k: K) => mapValues(fs, (f) => f(k)); // Looking for a function like mapValues
Currently, I can only achieve a record-like return using lodash mapValues or fp-ts Record.map:
{f1: typeof f1(k) | typeof f2(k), f2: typeof f1(k) | typeof f2(k)}
. My aim is to obtain a more precise mapping: {f1: typeof f1(k), f2: typeof f2(k)}
I believe fp-ts might have a solution for this, but I haven't found the right tool yet.
Is there a way to achieve this, or should I consider writing a custom mapValues function that respects the k=>v static relation?