数组缩减和typescript中的可选值

dag*_*da1 7 typescript

假设我有以下可折叠界面:

export interface Foldable<F> {
  reduce: <A>(fn: (b: A, a: A) => A, initial: A, foldable: F) => A;
}
Run Code Online (Sandbox Code Playgroud)

然后我想为数组实现它:

export const getArrayFold = <A>(): Foldable<Array<A>> => {
  return {
    reduce: (fn, initial, array) => {
      return array.reduce(fn, initial);
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨:

类型'(b:A,a:A)=> A'的参数不能分配给类型'的参数(previousValue:A,currentValue:A,currentIndex:number,array:A [])=> A'.参数'a'和'currentValue'的类型不兼容.类型"A"不能分配给"A"类型.存在两种具有此名称的不同类型,但它们是不相关的.

我不明白这里有两种不同的类型A.

Pio*_*ski 6

有两个错误:

  • 您需要提供哪种类型是数组。你不能从单一的 generic 得到它Array<T>,你需要同时引入Tand Array<T>
  • 您所消耗的函数类型reduce不合适。正确一:(previousValue: A, currentValue: F) => A

解释:

如果您提供具有类型(例如)的初始string以减少函数,则previousValue参数始终与inital相同。

请参阅官方TypeScript reduce 声明

interface Array<T> {
    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: ReadonlyArray<T>) => U, initialValue: U): U;
}
Run Code Online (Sandbox Code Playgroud)

完整代码(重构)

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);
Run Code Online (Sandbox Code Playgroud)

TypeScript 操场上查看代码