Этот вопрос в основном касается javascript лучших практик при внедрении поведения в объекты. У меня есть несколько небольших объектов, которые следуют некоторым интерфейсам:
export interface Semigroup<A> {
append(l: A, r: A): A;
}
export interface Monoid<A> extends Semigroup<A> {
empty(): A;
}
И несколько методов комбинатора, которые работают с этими объектами. Использование их в качестве цепочки методов намного приятнее.
Чтобы сделать набор методов stati c доступным для группы объектов, я вижу два очевидных решения:
- Создание прототипа установить объект и установить его для всех базовых типов
- Обернуть все базовые типы в адаптере, который передает базовое c поведение
В настоящее время я использую последний:
class AMonoid<A> implements Monoid<A> {
private theMonoid: Monoid<A>;
constructor(theMonoid: Monoid<A>) {
this.theMonoid = theMonoid;
}
append(l: A, r: A): A {
return this.theMonoid.append(l, r);
}
empty(): A {
return this.theMonoid.empty();
}
liftMap(): AMonoid<Map<any, A>> {
return liftMonoidToMap(this);
}
fold(): F.AFold<A, A> {
return foldMonoid(this);
}
}
export const sum = new AMonoid({
empty: () => 0,
append: (l,r) => l+r
});
Прототип решения кажется более javascript -y, но я беспокоюсь о непредвиденных побочных эффектах. Что произойдет, если у обернутого объекта есть один из служебных методов случайно? Можно ли заставить машинопись создавать ошибку типа в этом случае? Частные методы / свойства играют хорошо с этим?