(Edit I'm using monocle-ts, but if it's not possible with monocle-ts (since the author even says it's just a partial port of the original Monocle for Scala) but if there is something in another optics package for any language, I'm open to porting those ideas to TypeScript.)
Suppose I have a helper type Partial<A>
such that it represents a record that has some or all, but no non-members, of type A
. (So if A = { foo: number, bar: string }
then Partial<A> = { foo?: number, bar?: string }
) (Edit This is Typescript's built-in Partial utility type.)
I begin with
interface Parent {
xs: Child[]
}
interface PartialParent {
partialxs: Partial<Child>[]
}
declare function fillInTheGaps(x: Partial<Child>):Child
Suppose I have composed a lens and traversal composed (composedTraversal
) so that it focuses on partialxs
from PartialState
and then traverses over it as an array. This would be a Traversal<PartialState, Partial<Child>>
.
Posit also that I have a declare const fn = (x:Partial<Child>):Partial<Child>
then I can apply fn
to all children with composedTraversal.modify(fn)(partialState)
which will yield a new PartialState
with fn
applied to all of the partialxs
.
Is there some concept that lets me "broaden" or "transform" this traversal into something different so that I could compose the lens and traversal and use fillInTheGaps
so I can pass in the PartialState
and get back a State
?
Ignoring that my syntax is TypeScript, I've added the monocle-scala tag because if this concept exists I imagine it's in the Monocle library and I can translate that knowledge to the library I'm using.
Edit The problem motivating this question is I have a form input in a Redux app where a user inputs data but most is not required. The INPUTs are not known at compile-time (they're retried from a RESTful API query) so I cannot represent the model as
interface Model {
foo?: string[]
bar?: string[]
}
Instead, it is represented as
interface Model {
[index:string]: string[]
}
I can also fetch a default model from the RESTful server. So I've modeled these as Parent
(what comes from the server) and Partial<Parent>
(what represents the user's input in the app).
Before doing some computations, I need to fold in defaults for the missing props. This is my fillInTheGaps
function referenced above.
The desire was to enforce what this does via types in my code and, because I have a lot of optics already written, reuse some of that. I actually have a lens and traversal written to perform other operations on this data. myLens.compose(myTraversal).modify(fn)
takes a Partial<State>
and returns a Partial<State>
but I was hoping to compose these to end up with a function that takes the partial and returns the whole.
I could obviously just write const filler: (Partial<State>):State = myLens.compose(myTraversal).modify(fillInTheGaps)
and then throw a //@ts-ignore
above it and know it would work, but that seems, uh, fragile.
Partial<A>
" - that would be just the builtin one, no? – BergiLens
andTraversal
, how are they defined? What library are you using? Please link its documentation. – BergiPartialChild
a typo where you meantPartialState
? And how is the latter defined? – Bergi