如何使用打字稿制作笛卡尔产品?
这是我所追求的类型签名:
function cartesianProduct<T1, T2, T3, T4, T5, T6, T7, T8>([c1, c2, c3, c4, c5, c6, c7, c8]: [T1[], T2[], T3[], T4[], T5[], T6[], T7[], T8[]]): [T1, T2, T3, T4, T5, T6, T7, T8][];
function cartesianProduct<T1, T2, T3, T4, T5, T6, T7>([c1, c2, c3, c4, c5, c6, c7]: [T1[], T2[], T3[], T4[], T5[], T6[], T7[]]): [T1, T2, T3, T4, T5, T6, T7][];
function cartesianProduct<T1, T2, T3, T4, T5, T6>([c1, c2, c3, c4, c5, c6]: [T1[], T2[], T3[], T4[], T5[], T6[]]): [T1, T2, T3, T4, T5, T6][];
function cartesianProduct<T1, T2, T3, T4, T5>([c1, c2, c3, c4, c5]: [T1[], T2[], T3[], T4[], T5]): [T1, T2, T3, T4, T5][];
function cartesianProduct<T1, T2, T3, T4>([c1, c2, c3, c4]: [T1[], T2[], T3[], T4[]]): [T1, T2, T3, T4][];
function cartesianProduct<T1, T2, T3>([c1, c2, c3]: [T1[], T2[], T3[]]): [T1, T2, T3][];
function cartesianProduct<T1, T2>([c1, c2]: [T1[], T2[]]): [T1, T2][];
function cartesianProduct<T>(sets: T[][]): T[][] {
// implementation
}
这是我希望它能做的示例。给定:
const input = [
[ 'a', 'b' ],
[ 1, 2 ],
];
它会吐出来:
const output = [
[ 'a', 1 ],
[ 'a', 2 ],
[ 'b', 1 ],
[ 'b', 2 ],
];
尝试使用此参考实现给我们这个类型的问题:
Here's a playground。
Here's the type signature that I'm after:
function cartesianProduct<T1, T2, T3, T4, T5, T6, T7, T8>([c1, c2, c3, c4, c5, c6, c7, c8]: [T1[], T2[], T3[], T4[], T5[], T6[], T7[], T8[]]): [T1, T2, T3, T4, T5, T6, T7, T8][];
function cartesianProduct<T1, T2, T3, T4, T5, T6, T7>([c1, c2, c3, c4, c5, c6, c7]: [T1[], T2[], T3[], T4[], T5[], T6[], T7[]]): [T1, T2, T3, T4, T5, T6, T7][];
function cartesianProduct<T1, T2, T3, T4, T5, T6>([c1, c2, c3, c4, c5, c6]: [T1[], T2[], T3[], T4[], T5[], T6[]]): [T1, T2, T3, T4, T5, T6][];
function cartesianProduct<T1, T2, T3, T4, T5>([c1, c2, c3, c4, c5]: [T1[], T2[], T3[], T4[], T5]): [T1, T2, T3, T4, T5][];
function cartesianProduct<T1, T2, T3, T4>([c1, c2, c3, c4]: [T1[], T2[], T3[], T4[]]): [T1, T2, T3, T4][];
function cartesianProduct<T1, T2, T3>([c1, c2, c3]: [T1[], T2[], T3[]]): [T1, T2, T3][];
function cartesianProduct<T1, T2>([c1, c2]: [T1[], T2[]]): [T1, T2][];
function cartesianProduct<T>(sets: T[][]): T[][] {
// implementation
}
Here's an example of what I expect it to do. Given:
const input = [
[ 'a', 'b' ],
[ 1, 2 ],
];
It would spit out:
const output = [
[ 'a', 1 ],
[ 'a', 2 ],
[ 'b', 1 ],
[ 'b', 2 ],
];
Trying to utilize this reference implementation gives us this type problem:
Here's a playground.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想使用ramda,则可以使用
r.SequeSection
带有数组。
If you'd like to use Ramda, you can use
R.sequence
with arrays.对于此类问题,我一直喜欢首先从类型开始。
首先是提取数组的元素类型的类型:
是的,我知道
a [number]
存在,但这将在以后导致类型错误,因为a
将是结果从推断
。然后,一种列出数组列表并为我们提供其元素类型的类型。
它几乎就像
inputs.map((f)=&gt; elementType(f))
在代码中。最后,我们使用这种类型来定义cartesianproduct类型:
现在我们以类型进行了代码进行此操作:
这种惊人的实现是从这个出色的答案如果您的环境不支持
flat
或flatmap
,则可以在哪里找到其他替代方案。在实现此实现之后,我们添加了类型:
但是存在错误,因为返回类型与
redair
调用的类型不匹配。 Unfortunately I don't know a good way to rid the error but if a cast is acceptable:Playground
For problems like these I always like to start with the types first.
First a type to extract the element type of an array:
Yes, I know
A[number]
exists but this will result in type errors later on becauseA
will be a result frominfer
.Then a type that takes a list of arrays and gives us their element types.
It's almost like
Inputs.map((F) => ElementType(F))
in code.Finally we use this type to define a CartesianProduct type:
Now that we did it in types it's time to do it in code:
This amazing implementation was taken from this excellent answer where you can find other alternatives if your environment does not support
flat
orflatMap
.After we have this implementation we add the types:
But there is an error because the return type does not match the type of the
reduce
call. Unfortunately I don't know a good way to rid the error but if a cast is acceptable:Playground