Typescript: есть ли способ наложить универсальное ограничение на универсальный класс внутри метода? - PullRequest
1 голос
/ 14 июня 2019

У меня есть монадическая структура данных, которая выглядит следующим образом:

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>[]
}

Где Initial, Failed, Loaded и Loading - это четыре разные "формы" моего типа.

Иногда в моем коде я получаю 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 голосов
/ 14 июня 2019

Вы не должны вызывать 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(...)
//                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
...