Can types be inferred from an options object?
Here is my contrived example.
The idea here is I have a function that takes in an object, where fields are conversion functions (convert A to B, etc). The return of this function is an object with similar functions, but they have a slightly different return type.
I've put some generics in but I'm not really sure how to make it work. I've seen a similar design with Redux Toolkit's createSlice() function, but it's pretty complicated.
type InputActionFn = (arg: any) => any;
interface Options {
actions: {
[K: string]: InputActionFn;
};
}
interface ActionPayload<B> {
payload: B;
}
type OutputActionFn<A, B> = (arg: A) => ActionPayload<B>;
interface ConverterReturn {
actions: {
[K: string]: OutputActionFn<any, any>;
};
}
export function createConvertor(options: Options): ConverterReturn {
const actions: Record<string, OutputActionFn<any, any>> = {};
// For each key I create a function that returns my converted payload.
Object.keys(options.actions).forEach(key => {
actions[key] = arg => {
return {
payload: options.actions[key](arg),
};
};
});
return {
actions,
};
}
And this is how I plan on using it:
// I can specify as many converter functions here as I want
const conv = createConvertor({
actions: {
actionA: (a: number) => a.toFixed(),
actionB: (b: string) => parseInt(b, 10),
},
});
// actionA should be typed properly like this:
// actionA(arg: number) => ActionPayload<string>
const resultA = conv.actions.actionA(5);
console.log(resultA.payload);
// Outputs: "5"
const resultB = conv.actions.actionB('10');
console.log(resultB.payload);
// Outputs: 10