javascript - 通过对象展开一个参数对象传递参数给函数不起作用
我想通过像这个 SO 回答中那样展开一个 params 对象来传递所有参数给这个函数:
public showToast(
content: string,
buttonLabel = 'Ok',
hideDelay?: number,
buttonAction?: Function,
uniqueKey?: string,
canBeCleared?: boolean,
templateCtrl?: Object
): Toast {
const toast = new Toast(
content,
this,
buttonLabel,
hideDelay,
buttonAction,
uniqueKey,
canBeCleared,
templateCtrl
);
toast.id = !this.lastToast ? 1 : this.lastToast.id + 1;
this.toasts.push(toast);
toast.top = toast.fromTop;
// hiding is handled in the ToastComponent
return toast;
}
我的尝试:
const toastArgs = {
content: 'test toast',
buttonLabel: 'test button',
hideDelay: 1000,
buttonAction: () => 5,
uniqueKey: 'uk',
canBeCleared: true,
templateCtrl: { strl: 3 }
};
service.showToast(...Object.values(toastArgs));
编译时错误:
预期 1-7 个参数,但得到了 0 个或更多。ts(2556) toast.service.ts(18, 9):没有提供 'content' 参数。
我为什么会得到这个错误?我已经按照 SO 的答案做了。
答案#1
你会收到这个信息,因为 Object.values(toastArgs) 被推断为:
(true | "test toast" | "test button" | 1000 | (() => number) | "uk" | {
readonly strl: 3;
})[]
TypeScript 并不真正有数组“长度”的概念。在 TypeScript 看来,toastArgs 可能是 { x: true },它也会满足 Object.values(toastArgs) 的类型。你可以像下面这样测试:
const toastArgsValid = {
content: 'test toast',
buttonLabel: 'test button',
hideDelay: 1000,
buttonAction: () => 5,
uniqueKey: 'uk',
canBeCleared: true,
templateCtrl: {strl: 3},
};
const toastArgsValuesValid = Object.values(toastArgsValid);
type ToastParamsValid = typeof toastArgsValuesValid;
const toastArgsInvalid = {
x: true,
};
const toastArgsValuesInvalid: ToastParamsValid = Object.values(
toastArgsInvalid,
); // No error here since the invalid type is a subtype of the valid type
实现你所寻找的一个方法是重构你的 showToast 方法,使其接收一个对象,而不是位置参数:
public showToast({
content,
buttonLabel,
hideDelay,
buttonAction,
uniqueKey,
canBeCleared,
templateCtrl,
}: {
content: string;
buttonLabel: string;
hideDelay?: number;
buttonAction?: Function;
uniqueKey?: string;
canBeCleared?: boolean;
templateCtrl?: Object;
}): Toast {
// function body
}
你随后可以调用:
service.showToast(toastArgs)
或者你也可以使用类型断言,而无需像这样重构你的代码:
service.showToast(...(Object.values(toastArgs) as Parameters<typeof service.showToast>));
答案#2
Object.values() 从 es2017,即 ECMAScript_2017 开始被支持。而 TypeScript 的默认目标版本是 ES3。这个错误可以通过添加编译器选项 --target es2017 来修复。
