javascript - TypeScript 中类型参数的可选计数

标签 javascript typescript generics

我想创建具有可选类型参数数量的函数。例如,函数接受参数,其中每个参数都是数组并返回数组,其中第 n 项是第 n 个参数中的随机项:

const getRandomItems<T1, T2, T3>(...arrays: [T1[], T2[], T3[]]): [T1, T2, T3] = {
    const result = []

    for (const items of arrays) {
        result.push(items[Math.floor(Math.random() * items.length)])
    }

    return result
}

const fruits = ['Apple', 'Orange', 'Banana']
const colors = ['Red', 'Green', 'Blue']
const cars = [new Car('Ferrari'), new Car('Porsche')]

// E.g. ['Apple', 'Blue', new Car('Porsche')]
getRandomItems<string, string, Car>(friuts, colors, cars)

// E.g. ['Orange', new Car('Ferrari'), 'Red']
getRandomItems<string, Car, string>(friuts, cars, colors)

该函数接受 3 个参数并返回具有 3 个参数的数组。但是我可以创建函数吗:

  • 接受任意数量的类型化参数,例如。 G。 <T1, T2, T3, T4> ,
  • 接受与类型参数相同数量的参数:...arrays: [T1[], T2[], T3[], T4[]] ,
  • 返回与类型参数相同类型的数组:[T1, T2, T3, T4]
// Something like this:
const getRandomItems<...T>(...arrays: [...T[]]): [...T] = {

}

最佳答案

您需要使用 mapped type循环输入的类型并将每个数组类型转换为其元素的类型:

type UnwrapArray<T> = T extends (infer U)[] ? U : T;

type Result<T extends any[][]> = {
  [I in keyof T]: UnwrapArray<T[I]>;
}

function getRandomItems<T extends any[][]>(...arrays: T): Result<T> {
    const result = []

    for (const items of arrays) {
        result.push(items[Math.floor(Math.random() * items.length)])
    }

    return result as any;
}

首先,我们需要一个辅助类型 UnwrapArray从数组中提取元素的类型。请参阅this SO answer了解更多信息。

接下来,我们得到函数返回值的类型。它采用类型 T这是一个双重嵌套数组,迭代所有键 [I in keyof T] (因为这是一个数组,所以键是索引)并提取每个数组的元素类型 UnwrapArray<T[I]> .

最后,该函数只接受一个通用参数 T具有与 Result 相同的约束。这样,提供多少个参数并不重要。

注意:需要将结果转换为 any在函数体内部,因为编译器对 Result<T> 没有足够高的理解事实上是。

Playground

关于javascript - TypeScript 中类型参数的可选计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57852373/

相关文章:

Angular 5 - Jasimine 测试 - 错误 : Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed

javascript - 具有状态管理的 Angular 4 中的顺序(事务性)API 调用

c# - 通用列表 c#

swift - 如何为 NSFetchRequest 转换 T.Type?

java - 使用 Java 泛型可能会挂起编译器

javascript - 正则表达式错误 :nothing to repeat

javascript - 也使 array.filter 过滤空值

javascript - 为什么 "colspan"在我的表中不起作用

javascript - 在Vue.js中的双大括号{{}}中渲染元素

typescript - 对象字面量出现“不可分配给类型参数”错误