假设我有以下可折叠界面:
export interface Foldable<F> {
reduce: <A>(fn: (b: A, a: A) => A, initial: A, foldable: F) => A;
}
然后我想为数组实现它:
export const getArrayFold = <A>(): Foldable<Array<A>> => {
return {
reduce: (fn, initial, array) => {
return array.reduce(fn, initial);
}
};
};
但是编译器提示:
Argument of type '(b: A, a: A) => A' is not assignable to parameter of type '(previousValue: A, currentValue: A, currentIndex: number, array: A[]) => A'. Types of parameters 'a' and 'currentValue' are incompatible. Type 'A' is not assignable to type 'A'. Two different types with this name exist, but they are unrelated.
我不明白为什么这里有两种不同类型的A
。
最佳答案
有两个错误:
- 您需要提供数组类型。您无法从单个通用
Array<T>
获得它, 你需要同时介绍T
和Array<T>
. reduce
使用的函数类型是不够的。正确一个:(previousValue: A, currentValue: F) => A
解释:
如果您提供具有类型(例如 string
)的 initial 值来减少函数,previousValue 参数始终与 inital 相同。
见官方TypeScript reduce declaration :
interface Array<T> {
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => U, initialValue: U): U;
}
完整代码(重构)
interface Foldable<F, T> {
reduce: <A>(
fn: (previousValue: A, currentValue: T) => A,
initial: A,
foldable: F
) => A;
}
const getArrayFold = <T>(): Foldable<T[], T> => ({
reduce(fn, initial, array) {
return array.reduce(fn, initial);
}
});
// Real implementation usage
const array: number[] = [1, 2, 3]
const initial: string = "";
const fn: (previousValue: string, currentValue: number) => string = (a, b) => a + b;
const newValue: string = getArrayFold().reduce(fn, initial, array);
参见 TypeScript playground 上的代码
关于typescript - typescript 中的数组减少和可选值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50031247/