I'm creating a function that receives multiple keys and values and should return an object having those keys and their respective values. The Value types should match the values I passed when I called the function.
Currently, the code works, but the typings are not exact.
I tried using the Factory way, hoping that typescript could infer something for me.
Here is the code for the factory. Also, there is a playground here.
const maker = (subModules?: Record<string, unknown>) => {
const add = <Name extends string, Q>(key: Name, value: Q) => {
const obj = {[key]: value};
return maker({
...subModules,
...obj
})
}
const build = () => {
return subModules
}
return {
add,
build
}
}
const m2 = maker()
.add('fn', ({a, b}: { a: number, b: number }) => a + b)
.add('foo', 1)
.add('bar', 'aaaa')
.build()
// m2.foo -> 1
// m2.bar -> 'aaaa'
// m2.fn({a: 1, b: 2}) -> 3
m2
Also there is the option for pipeline(playground) maybe this one could be easier:
type I = <T extends any[]>(...obj: T) => { [P in T[number]['key']]: T[number]['value'] }
const metaMaker: I = <T extends any[]>(...subModules: T) => {
return subModules.reduce((acc, curr) => {
const op = {[curr.key]: curr.value}
return {
...acc,
...op
}
}, {}) as { [P in T[number]['key']]: T[number]['value'] }
}
const m = metaMaker(
{key: 'fn', value: ({a, b}: { a: number, b: number }) => a + b},
{key: 'foo', value: 1},
{key: 'bar', value: 'aaaa'},
)
// m.foo -> 1
// m.bar -> 'aaaa'
// m.fn({a: 1, b: 2}) -> 3
// m