【问题标题】:Pass in params to function by object spreading a params object not working通过传播参数对象不起作用的对象传递参数以发挥作用
【发布时间】:2020-08-04 16:38:00
【问题描述】:

我想通过传播一个params对象like this SO answer将所有参数传递给这个函数:

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): 没有提供“内容”的参数。

为什么会出现此错误?我已经按照 SO 回答了。

【问题讨论】:

  • 完整的错误消息、编译器选项和 TypeScript 的版本可能会有所帮助。

标签: javascript typescript ecmascript-6


【解决方案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。只需添加 compiler option --target es2017 即可修复该错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 1970-01-01
      • 2021-07-30
      • 2015-02-05
      相关资源
      最近更新 更多