Typescript:有没有办法将通用约束放在方法内部的通用类上?

时间:2019-06-14 09:12:09

标签: javascript arrays typescript monads

我有一个像这样的单子数据结构:

export abstract class Data<A> {
  static initial<A>(): Data<A> {
    return new Initial<A>()
  }

  static failed<A>(error?: any): Data<A> {
    return new Failed<A>(error)
  }

  static loaded<A>(value: A): Data<A> {
    return new Loaded<A>(value)
  }

  static loading<A>(): Data<A> {
    return new Loading<A>()
  }

  static getData<A>(data: Loaded<A>): A {
    return data.getData()
  }

  constructor(public readonly kind: Kind) {}

  abstract map<B>(f: (a: A) => B): Data<B>

  abstract chain<B>(f: (a: A) => Data<B>): Data<B>

  abstract flatMap<B>(f: (a: A) => Data<B[]>): Data<B>[]
}

InitialFailedLoadedLoading是我类型中的四个不同“形状”。

有时在我的代码中得到一个Data<A>[],我想根据A上的条件进行过滤。我当前的实现是这样:

  static filter<A>(data: Data<A>[], pred: (a:A) => boolean): Data<A>[] {
    return data.filter(datum => {
      if(datum.isLoaded()) {
        return pred(datum.data)
      }
      return false
    })
  }

大多数代码使用链式方法,例如:

data.map(...).filter(...).doThis().doThat()

但是由于static,有时订单会变得混乱:

Data.filter(data.map(...).flatMap(...), myPredicate).map(...).doThis(...) ........

我想知道是否有一种方法可以使此函数变为非静态,并使用“流利的”样式链接方法?

我应该为此扩展数组的原型吗?

1 个答案:

答案 0 :(得分:0)

您不应该在Array::filter函数中调用filter,而应该返回包装的谓词函数:

static loadedAnd<A>(pred: (a:A) => boolean): Data<A> => boolean {
  return datum => datum.isLoaded() && pred(datum.data);
}

随你写

data.map(...).flatMap(...).filter(Data.loadedAnd(myPredicate)).map(...).doThis(...)
//                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^