(Edit I使用的是单片,但如果单ocle-ts是不可能的(因为作者甚至说它只是Scala原版Monocle的一个部分端口),但是如果任何语言的另一个光学包中有什么东西,我愿意将这些想法移植到TypeScript。
假设我有一个助手类型Partial<A>,这样它就代表了一个记录,该记录具有A类型的部分或全部,但没有非成员。(因此,如果A = { foo: number, bar: string }那么Partial<A> = { foo?: number, bar?: string }) (编辑,这是类型记录的内置部分实用程序类型)。
我首先
interface Parent {
xs: Child[]
}
interface PartialParent {
partialxs: Partial<Child>[]
}
declare function fillInTheGaps(x: Partial<Child>):Child假设我已经组成了一个透镜和遍历组合(composedTraversal),这样它就可以聚焦于来自PartialState的partialxs,然后作为一个数组遍历它。这将是一个Traversal<PartialState, Partial<Child>>。
另外,假设我有一个declare const fn = (x:Partial<Child>):Partial<Child>,那么我可以将fn应用于所有composedTraversal.modify(fn)(partialState)儿童,这将产生一个新的PartialState,并将fn应用于所有partialxs。
是否有什么概念可以让我“扩大”或“将”这个遍历变成不同的东西,这样我就可以组合镜头和遍历,并使用fillInTheGaps,这样我就可以传入PartialState并返回一个State。
忽略了我的语法是TypeScript,我添加了monocle-scala标记,因为如果这个概念存在的话,我想它就在Monocle库中,我可以将这些知识转换到我正在使用的库中。
编辑引发这个问题的问题是,我在一个Redux应用程序中有一个表单输入,其中用户输入数据,但大多数不是必需的。输入在编译时不知道(它们是从RESTful API查询重试的),所以我不能将模型表示为
interface Model {
foo?: string[]
bar?: string[]
}相反,它被表示为
interface Model {
[index:string]: string[]
}我还可以从RESTful服务器获取默认模型。因此,我将它们建模为Parent (来自服务器的内容)和Partial<Parent> (代表用户在应用程序中的输入)。
在进行一些计算之前,我需要折叠丢失的道具的默认值。这是上面引用的我的fillInTheGaps函数。
我们的愿望是通过代码中的类型来实现这一点,而且,因为我已经编写了很多光学软件,所以可以重用其中的一些内容。实际上,我已经编写了一个镜头和遍历来对这些数据执行其他操作。myLens.compose(myTraversal).modify(fn)接受一个Partial<State>并返回一个Partial<State>,但是我希望将它们组合成一个函数,该函数接受部分并返回整个函数。
很明显,我可以直接写const filler: (Partial<State>):State = myLens.compose(myTraversal).modify(fillInTheGaps),然后在上面加一个//@ts-ignore,知道它能用,但这看起来,呃,很脆弱。
发布于 2020-09-08 23:25:18
我想,你可能想要一个PTraversal。
一个Traversal<S, A>说,“如果我有一个函数A => A,我可以使用modify获得一个函数S => S,它使用原始函数来修改出现在S中的所有A”。
相比之下,PTraversal<S, T, A, B>说,“如果我有一个函数A => B,我可以使用modify获得一个函数S => T",这会将S中的所有A转换为B,从而生成一个T。
PTraversal的类型参数是:
S是PTraversal的来源T -- PTraversal的“修改”源A -- PTraversal的目标B -- PTraversal的“修改”目标PTraversal是有用的,因为它们允许您编写如下内容:
PTraversal<Array<A>, Array<B>, A, B>允许您在更改元素类型的同时遍历Array。
在您的具体案例中,您提到了具有两个功能:
declare function fillInTheGaps(x: Partial<Child>):Child
declare function fn(x: Partial<Child>):Partial<Child>这些功能可以一起组成,以产生一个单一的功能:
function transformAndFill(x: Partial<Child>): Child {
return fillInTheGaps(fn(x));
}然后,您需要编写一个PTraversal<PartialState, State, Partial<Child>, Child>。
这将支持使用Lens进行组合,从而以与Traversal相同的方式生成新的PTraversal。
这应该是可行的,我认为从您的问题中可以看出,如果您可以将PartialState中的每个PartialState转换为Child,那么您应该能够生成一个State。
PTraversal存在于Monocle ( Scala库)中,但不幸的是,它看起来不像是将其转换为monocle-ts:因此不幸的是,您必须编写相当多的光学库代码才能支持这一点。
https://stackoverflow.com/questions/63749061
复制相似问题