Nic*_*cky 3 cartesian-product typescript typescript4.0 variadic-tuple-types
TypeScript 4.0 开始支持Variadic Tuple Types的概念,这是一种很好的类型构造,可以在连接函数等中使用。文档中的一个示例:
type Arr = readonly any[];
function concat<T extends Arr, U extends Arr>(arr1: T, arr2: U): [...T, ...U] {
return [...arr1, ...arr2];
}
Run Code Online (Sandbox Code Playgroud)
我感兴趣的是这种类型构造是否可用于键入笛卡尔积函数。然后,该函数应从参数推断(混合)类型以生成其返回类型。因此,如果我输入,[number[], string[]]我希望输出的类型为[number, string][]. 在此线程中可以找到笛卡尔积的多个实现,但没有一个是严格类型化的。这是一个例子:
const cartesian =
(...a) => a.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat())));
Run Code Online (Sandbox Code Playgroud)
我当前使用的实现不使用可变元组类型,并且需要显式类型转换:
const cartesian = <T extends any[]>(...arr: any[][]): T[] =>
arr.reduce<T[]>(
(a, b) => a.flatMap<T>(c => b.map<T>(d => [...c, d] as T)),
[[]] as T
);
const product = cartesian<[number, string]>([1, 2, 3], ['a', 'b', 'c']);
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种无需显式类型转换的解决方案,并且我认为可变元组类型可能是这里合适的类型构造。
问题
如何使用可变元组类型来推断笛卡尔积函数的类型?
我不认为可变元组类型实际上改善了我们输入的方式。自从 3.1 中添加了对映射元组的支持以来,键入此内容实际上是可能的(以前可能是可能的,但不那么干净)。
在实际实现中您仍然需要类型断言,但调用站点将推断参数类型并生成正确的返回类型:
type MapCartesian<T extends any[][]> = {
[P in keyof T]: T[P] extends Array<infer U>? U: never
}
const cartesian = <T extends any[][]>(...arr: T): MapCartesian<T>[] =>
arr.reduce(
(a, b) => a.flatMap(c => b.map(d => [...c, d] )),
[[]]
) as MapCartesian<T>[];
const product = cartesian([1, 2, 3], ['a', 'b', 'c']);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1325 次 |
| 最近记录: |