我试图在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.