使用乘法参数在JS中减少函数?



我有这个类方法:

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'.

我假设您要做的是将布尔值强制为 0 或 1,将它们相乘以确定是否有任何零,然后将结果数字强制回布尔值以用于if

打字稿不喜欢这个想法。 虽然它可能适用于原始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 注释。 但是我发现当条件表达式较短时,最好在一行上,更容易遵循。

最新更新