Skip to content

Instantly share code, notes, and snippets.

@janwirth
Last active August 21, 2018 12:09
Show Gist options
  • Save janwirth/9cbe48cdd4ab9a21caae92bb0cd7808d to your computer and use it in GitHub Desktop.
Save janwirth/9cbe48cdd4ab9a21caae92bb0cd7808d to your computer and use it in GitHub Desktop.
console.log('hi')
type Focus<T, T2> = (obj: T) => T2
const setIn = <T, T2>(expr: Focus<T, T2>) => (obj: T) => {
// convert path to array of strings
const propAccess = /\.([A-Za-z](\.[A-Za-z])*)/
const path: string[] = expr.toString()
.match(propAccess)[1]
.split('.')
// set
let targetObj = {} as any
// focused depth in object
let focused = targetObj
// create skeleton
path.forEach((prop, depth, path) => {
if (depth < path.length - 1) {
focused[prop] = {}
focused = focused[prop]
console.log(prop, 'focused', JSON.stringify(focused, null, 2))
} else {
expr(targetObj)
}
})
// merge source and target
// return Object.assign(targetObj, obj)
return Object.assign({}, obj, targetObj)
}
const A = { a: 'b' }
console.log("{ a: 'yo' }", setIn<{ a: string }, string>(obj => obj.a = 'yo')(A))
console.log('A', A)
console.log("{ a: 'x', b: { c: 'yo' }}", setIn<{ a: string, b: { c: string } }, string>(obj => obj.b.c = 'yo')({ a: 'x', b: { c: 'a' } }))
console.log("{ a: 'c'}", setIn<{ a: string }, string>(obj => obj.a = 'c')({ a: 'b' }))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment