Challenging Situation
I'm new to typescript and facing the task of converting the mapProps
function provided below into typescript
const addOne = x => x + 1
const upperCase = x => x.toUpperCase()
const obj = {
entry: 'legend',
fauna: {
unicorns: 10,
zombies: 3
},
other: {
hat: 2
}
}
const fns = {
entry: upperCase,
fauna: {
unicorns: addOne
},
other: obj => ({
hat: addOne(obj.hat)
})
}
const mapProps = (obj, fns) =>
Object.keys(fns).reduce(
(acc, cur) => ({
...acc,
[cur]: fns[cur] instanceof Function
? fns[cur](obj[cur])
: mapProps(obj[cur], fns[cur])
}),
obj
)
mapProps(obj, fns)
// { entry: 'LEGEND', fauna: { unicorns: 11, zombies: 3 }, other: { hat: 3 } }
Current Struggle
type MapPropFuncsOf<T> = {
[P in keyof T]?: ((x:T[P]) => T[P]) | MapPropFuncsOf<T[P]>
}
const mapProps = <T>(obj:T, fns: MapPropFuncsOf<T>) =>
(Object.keys(fns) as (keyof T)[]).reduce(
(acc, cur) => ({
...acc,
[cur]: fns[cur] instanceof Function
? fns[cur]!(obj[cur]) // compiler warning
: mapProps(obj[cur], fns[cur]) // compiler warning
}),
obj
)
Obstacles Faced
Despite validating that fns[cur] instanceof Function
, I am struggling to call fns[cur]
. The typescript compiler raises the following errors:
Cannot invoke an expression whose type lacks a call signature. Type 'MapPropFuncsOf | ((x: T[keyof T]) => T[keyof T])' has no compatible call signatures.
The call to mapProps(obj[cur], fns[cur])
also encounters issues with the compiler reporting:
Argument of type 'MapPropFuncsOf | ((x: T[keyof T]) => T[keyof T]) | undefined' is not assignable to parameter of type 'MapPropFuncsOf'. Type 'undefined' is not assignable to type 'MapPropFuncsOf'.