(编辑我正在使用monocle-ts,但是如果使用 monocle-ts 是不可能的(因为作者甚至说它只是 Scala 原始 Monocle 的部分端口)但是如果在另一个光学包中有任何语言的东西,我愿意将这些想法移植到 TypeScript。)
假设我有一个辅助类型Partial<A>
,它表示一个记录,该记录具有类型的部分或全部,但没有非成员A
。(所以如果A = { foo: number, bar: string }
then Partial<A> = { foo?: number, bar?: string }
)(编辑这是 Typescript 的内置 Partial 实用程序类型。)
我从
interface Parent {
xs: Child[]
}
interface PartialParent {
partialxs: Partial<Child>[]
}
declare function fillInTheGaps(x: Partial<Child>):Child
假设我已经组合了一个镜头并遍历组合 ( composedTraversal
) 以便它聚焦于 partialxs
fromPartialState
然后作为一个数组遍历它。这将是一个Traversal<PartialState, Partial<Child>>
.
还假设我有一个declare const fn = (x:Partial<Child>):Partial<Child>
然后我可以应用于fn
所有孩子,composedTraversal.modify(fn)(partialState)
这将产生一个新PartialState
的fn
应用于所有partialxs
.
是否有一些概念可以让我“扩大”或“转换”这个遍历到不同的东西,以便我可以组成镜头和遍历并使用fillInTheGaps
,这样我就可以传入PartialState
并取回 a State
?
忽略我的语法是 TypeScript,我添加了 monocle-scala 标签,因为如果这个概念存在,我想它在 Monocle 库中,我可以将这些知识翻译到我正在使用的库中。
编辑激发这个问题的问题是我在 Redux 应用程序中有一个表单输入,用户输入数据但大多数不是必需的。INPUT 在编译时是未知的(它们是从 RESTful API 查询中重试的),所以我不能将模型表示为
interface Model {
foo?: string[]
bar?: string[]
}
相反,它表示为
interface Model {
[index:string]: string[]
}
我还可以从 RESTful 服务器获取默认模型。所以我将这些建模为Parent
(来自服务器的Partial<Parent>
内容)和(代表用户在应用程序中的输入)。
在进行一些计算之前,我需要为缺少的道具折叠默认值。这是我fillInTheGaps
上面引用的函数。
希望通过我的代码中的类型来强制执行此操作,并且因为我已经编写了很多光学元件,所以重用其中的一些。实际上,我编写了一个镜头和遍历来对这些数据执行其他操作。myLens.compose(myTraversal).modify(fn)
接受 aPartial<State>
并返回 aPartial<State>
但我希望将这些组合起来最终得到一个接受部分并返回整体的函数。
我显然可以只写const filler: (Partial<State>):State = myLens.compose(myTraversal).modify(fillInTheGaps)
然后//@ts-ignore
在它上面扔一个并且知道它会起作用,但这似乎,呃,脆弱。