首页 > 解决方案 > 映射元组类型/数组:将数组作为元组传递给函数

问题描述

我想要做的是将一个数组传递给一个函数,并将这个数组的值作为另一个函数中的元组接收。

myFunction(
    (a, b) => null,
    {
        params: [true, 1]
    }
);

在上面的示例中,我想要输入:a: booleanb: number. 相反,我收到a: boolean | numberand b: boolean | number

请记住,我希望参数的长度是可变的。也[1, false, 'string', {}]应该可以。

正如我所读到的,这与映射元组有关吗?但我真的不明白。

我当前的实现如下所示:

function myFunction<P extends any[]>(
    fn: (...params: P) => null, 
    options: { params: P }) {
    ...
}

--

实际有效的是:

myFunction(
    (a, b) => null,
    {
        params: [true, 1] as [boolean, number]
    }
);

但我真的不想一直进行类型转换以使其工作:/

标签: typescriptmapped-types

解决方案


更新:

实际上有一个更简单的方法。通常,只有函数的调用者才能将数组缩小为元组类型as const(参见原始答案)。我们可以通过包含一个元组类型作为联合类型的组成部分来将此责任转移到P函数的泛型类型参数上,因此约束现在变为。myFunctionP extends (ReadonlyArray<any> | readonly [any])

function myFunction<P extends (ReadonlyArray<any> | readonly [any])>(
  fn: (...params: P) => null,
  options: { params: P }
) {
  fn(...options.params)
  // ...
}

myFunction((a, b) => null, {
  params: [true, 1]
});

// params: [boolean, number]
// fn: (a: boolean, b: number) => null

操场

归功于 jcalz的回答,其中涉及我在这里找到的一些“巫术代码”。也看看相关的功能建议

原答案:

虽然我不太了解你的用例,但是这个呢?

// fn: (params_0: true, params_1: 1, params_2: Date) => null
myFunction((a, b) => null, {
  params: ([true, 1, new Date()]) as const
}); 

function myFunction<P extends readonly any[]>(
  fn: (...params: P) => null,
  options: { params: P }
) { fn(...options.params); }

您仍然使用const assertion,但不必手动编写所有元组项类型。我假设,您只需将您的params直接传递给回调,因为没有办法以某种方式操作P内部myFunction主体,您依赖于元组项目类型,因为P仅受限制于 extend any[]

一般来说Array,如果您在初始化时不使用as const.

const options = {
  params: [3,4,"a"] // params: (string | number)[];
}

const optionsConst = {
  params: [3,4,"a"] as const // params: readonly [3, 4, "a"];
}

操场


推荐阅读