Skip to content

Instantly share code, notes, and snippets.

@benbenbenbenbenben
Created March 8, 2024 16:35
Show Gist options
  • Save benbenbenbenbenben/69a7d5bc14549666689de1f9a55239f4 to your computer and use it in GitHub Desktop.
Save benbenbenbenbenben/69a7d5bc14549666689de1f9a55239f4 to your computer and use it in GitHub Desktop.
mutating vs cloning fluent API
type Value = {
value: number
}
type ValueWithUse = Value & {
use: (x: number) => ValueWithUse
}
// patch a fluent API to a Value object with side effects
const withMutatingUse = (thing: Value): ValueWithUse => {
const use = (x: number) => {
thing.value += x
return thing
}
return Object.assign(thing, { use }) as ValueWithUse
}
const boxWithMutatingUse = withMutatingUse({ value: 0 })
// add 1 three times
const valueFromMutatingApi = boxWithMutatingUse
.use(1)
.use(1)
.use(1)
.value
// expecting 3, 3
console.log(`value from chained call to mutating API: ${valueFromMutatingApi}`)
console.log(`value from boxWithMutatingUse: ${boxWithMutatingUse.value}`)
// patch a fluent API to a Value object without side effects
const withCloningUse = (thing: Value): ValueWithUse => {
const clone = structuredClone(thing)
const use = (x: number) => {
clone.value += x
return withCloningUse(clone)
}
return Object.assign(thing, {use}) as ValueWithUse
}
const boxWithCloningUse = withCloningUse({ value: 0 })
// add 1 three times
const valueFromCloningApi = boxWithCloningUse
.use(1)
.use(1)
.use(1)
.value
// expecting 3, 0
console.log(`value from chained call to cloning API: ${valueFromCloningApi}`)
console.log(`value from boxWithCloningUse: ${boxWithCloningUse.value}`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment