在我们称为searchForAcceptableNumber
的函数中有一系列谓词。
searchForAcceptableNumber(arrayOfNumbers: number[], ...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>): number[] {
const acceptableNumbers: number[] = [];
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (aNumber: number) => {
const isLabelAcceptableReducer = (accumulator, currentValue) => accumulator && currentValue(aNumber);
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer);
};
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber);
}
});
return acceptableNumbers;
}
您明白了。从本质上讲,它会反复进行,所有工作都很好……除了isNumberAcceptablePredicate
不断出现类型为(aNumber: number) => (aNumber: number) => boolean
的错误外,其他一切都很好。我可以摆脱这种类型,它将全部编译并正常工作。奇怪的是,如果我在调试会话期间将鼠标悬停在isNumberAcceptablePredicate
上,它表示确实是(aNumber: number) => boolean
类型。
这不一定是代码中断,也就是说,我最终将此谓词传递给需要类型(aNumber: number) => boolean
的其他函数,因此它确实引入了代码中断并增加了约束。我确定我缺少一些荒谬的东西,我只是无法分辨。
答案 0 :(得分:1)
您只需要向reduce函数提供一个初始值,否则默认使用数组中的第一个元素作为初始值,其类型为(aNumber: number) => boolean
而不是boolean
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
const acceptableNumbers: number[] = []
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (
aNumber: number,
) => {
const isLabelAcceptableReducer = (accumulator, currentValue) =>
accumulator && currentValue(aNumber)
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer, true) // <-- initialise to true
}
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber)
}
})
return acceptableNumbers
}
您还可以使用诸如此类的内置数组函数大大缩短此函数
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
return arrayOfNumbers.filter(number =>
isNumberAcceptablePredicates.every(predicate => predicate(number)),
)
}
如果要概括实现,可以执行以下操作
function filterList<T>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] {
return values.filter(val => predicates.every(pred => pred(val)))
}
您还可以使用箭头函数,因为该函数仅返回一个值,有些人出于简洁的目的而喜欢它
const filterList = <T extends any>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] => values.filter(val => predicates.every(pred => pred(val)))
注意:尽管<T extends any>
在语义上是多余的,但extends any
的原因还是有必要的,因为<T>
本身在语法上是模棱两可的,可以视为JSX
标记