我想做的是将一个数组传递给一个函数,并在另一个函数中将该数组的值作为元组接收。
myFunction(
(a, b) => null,
{
params: [true, 1]
}
);
在上面的示例中,我要输入:a: boolean
和b: number
。相反,我收到a: boolean | number
和b: boolean | number
。
请记住,我希望参数的长度可变。 [1, false, 'string', {}]
也应该是可能的。
如我所读,这与mapped tuples有关系吗?但是我真的不明白。
我当前的实现如下:
function myFunction<P extends any[]>(
fn: (...params: P) => null,
options: { params: P }) {
...
}
-
这实际上是有效的:
myFunction(
(a, b) => null,
{
params: [true, 1] as [boolean, number]
}
);
但是我真的不想一直都进行类型转换以使其正常工作:/
答案 0 :(得分:1)
实际上有一种更简单的方法。通常,只有使用as const
的函数调用者才能将数组缩小为元组类型(请参阅原始答案)。我们可以通过including a tuple type as constituent of an uniontype将这一责任移到函数P
的泛型类型参数myFunction
上,因此约束现在变成P 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的信用归answer所用,涉及一些“巫术代码” code我在这里捡到了。还可以查看相关的feature suggestion。
尽管我不太了解您的用例,但是呢?
// 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
仅限于扩展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"];
}
答案 1 :(得分:0)
您的声明代码正确。
这是调用函数的正确方法:
myFunction<[number, boolean]>(
(a, b) => null,
{params: [1, true]}
);
答案 2 :(得分:0)
尝试一下:
function myFunction<A, B, P extends [A, B]>(
fn: (...params: P) => null,
options: { params: P }) {
...
}