用乘法参数减少JS中的功能?

时间:2018-08-31 18:33:12

标签: javascript typescript

我有这个课堂方法:

public _controlValid(form: FormGroup, fieldName: string[], enableFieldName: string) {
    if (fieldName.map(field => {
      return form.controls[field].valid;
    }).reduce(function (a: number, b: number) {
      return a * b;
    })) {
      form.controls[enableFieldName].enable();
    } else {
      form.controls[enableFieldName].disable();
    }
  }

这段代码迭代字符串数组,并尝试获取每个控件的状态。然后reduce乘以map的这些返回值。

编译后,我收到此错误消息:

error TS2345: Argument of type '(a: number, b: number) => number' is not assignable to parameter of type '(previousVal
ue: boolean, currentValue: boolean, currentIndex: number, array: boolean[]) => boolean'.
  Types of parameters 'a' and 'previousValue' are incompatible.
    Type 'boolean' is not assignable to type 'number'.

1 个答案:

答案 0 :(得分:2)

我假设您要执行的操作是将布尔值强制为0或1,然后将它们相乘以确定是否存在零,然后将结果数字强制返回为布尔值以供if使用。

Typescript不喜欢这个想法。虽然它可能可以在原始Javascript中运行,但Typescript拒绝。

您可以通过将布尔值上的reduce替换为every来解决此问题:

function _controlValid(form: FormGroup, fieldName: string[], enableFieldName: string) {
  if (fieldName.map(field => {
    return form.controls[field].valid;
  }).every((a: boolean) => a)) {
    form.controls[enableFieldName].enable();
  } else {
    form.controls[enableFieldName].disable();
  }
}

如果您方便使用identity函数((x) => x),则可以更清楚地编写.every(identity)

清洁剂

但是对于此代码,仍然有些困扰我。该if条件确实很难阅读。我可能会分解两个辅助函数来清理它:

const allTrue = (xs) => xs.every(x => x);
const fieldsValid = (controls, names) => names.map(n => controls[n].valid)

function _controlValid(form: FormGroup, fieldName: string[], enableFieldName: string) {
  if (allTrue(fieldsValid(form.controls, fieldName))) {
    form.controls[enableFieldName].enable();
  } else {
    form.controls[enableFieldName].disable();
  }
}

您可能需要一些Typescript注释。但是我发现,当条件表达式较短时(最好在一行中),遵循起来会容易得多。