在typescript函数中扩展数组:错误TS2556



我试图在typescript函数调用上使用扩展操作符:

function foo(x: number, y: number, z: number) {
console.log(x + y + z);
}
const args = [0, 1, 2];
foo(...args);

但是在编译时,我得到错误:"扩展参数必须具有元组类型或传递给rest参数"(TS2556)。我做错了什么?

附录:当我的参数是一个动态数组时,如

,我该如何处理这个问题?
const args = new Array(3).map(() => Math.random());

编辑动态生成的args:

选项一:使用类型断言如果你确定args将始终是3个元素的元组

const args = new Array(3).map(() => Math.random()) as [number, number, number];

选项二,定义foo接受rest参数:

function foo(...args: number[]) {
console.log(args[0] + args[1] + args[2]);
}
const args = new Array(3).map(() => Math.random());
foo(...args);

预定义args的旧答案

可以将args断言为const:

const args = [0, 1, 2] as const;

游乐场

或者像错误提示那样将args定义为元组:

const args: [number, number, number] = [0, 1, 2];

游乐场

这是为了保证args中元素的数量/类型总是与函数参数所要求的匹配。

可以使用const assertion为了解决这个问题。因为函数foo只需要3个参数:

function foo(x: number, y: number, z: number) {
console.log(x + y + z);
}
const args = [0, 1, 2] as const;
foo(...args);

参数不是这样工作的,这是你应该如何设置它们的参数

function multiply(n, ...m) {
return m.map((x) => n * x);
}
// 'a' gets value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);

对于动态推断的参数大小,as const方法不起作用。

另一个解决方案是在.apply()调用中使用...args产生的数组。Typescript不会抱怨这个:

export class CustomError<
ErrorCode extends keyof typeof CustomError.codes,
ErrorParams extends Parameters<typeof CustomError.codes[ErrorCode]>
> extends Error {
constructor(public code: ErrorCode, ...args: ErrorParams) {
super(CustomError.codes[code].apply(null, args))
}
static codes = {
invalidEmail (email: string) {
return `Email ${email} is invalid`
},
invalidPasswordConfirm: (a: string, b: string) {
return `Password ${a} and confirm ${b} are different`
}
}
}
new CustomError('invalidEmail', 'aaa@bbb')
// ^ CustomError(code: "invalidEmail", email: string)
new CustomError('invalidPasswordConfirm', 'first', 'second')
// ^ CustomError(code: "invalidPasswordConfirm", a: string, b: string)

无论谁遭受A spread argument must either have a tuple type or be passed to a rest parameter.,你可能想检查typescript-parser是否安装在你的devDependencies.