Хочу написать функцию, которая принимает базовый класс + массив классов, свойства и методы которых должны примешиваться к базовому, и возвращает новый класс, состоящий из свойств и методов базового класса с этими самыми примесями. С методами проблем нет, затык возникает со свойствами, особенно с приватными.
Допустим, есть такие классы, которые я хочу подмешать к классу
class SomeClass1 {
#privateParam: string;
constructor() {
this.#privateParam = 'Some private value'
}
getPrivate() {
return this.#privateParam;
}
}
class SomeClass2 {
getSomeEntities() {
return "Hello, World!";
}
}
// И мапа для удобства обращения
const classesMap = new Map()
classesMap.set('SomeClass1', SomeClass1)
classesMap.set('SomeClass2', SomeClass2)
Вот несколько упрощенная функция, которая сами миксины примешивает
const getMixedClass = (Class: any, classes: any[]) => {
classes.forEach((item) => {
Object.getOwnPropertyNames(item.prototype).forEach((name) => {
Class.prototype[name] = item.prototype[name];
});
});
};
Далее мне нужна функция, которая получает, скажем, массив строк-указателей на классы-примеси и возвращает новый класс, либо сразу экземпляр класса с примешанными методами и свойствами запрашиваемых классов. Например:
const props = ['SomeClass1', 'SomeClass2']
class InitialClass {}
interface InitialClass extends SomeClass1, SomeClass2, SomeClassN {}
const instanceGenerator = (props: string[]) => {
getMixedClass(
InitialClass,
props.reduce((acc, next) => {
if (classesMap.has(next)) {
acc.push(classesMap.get(next))
}
return acc
}, [])
)
return new InitialClass()
}
const x = instanceGenerator(props)
console.log(x.getSomeEntities()) // Тут все норм, возвращается "Hello, World!"
console.log(x.getPrivate()) // А вот тут ошибка - TypeError: attempted to get private field on non-instance
Если же сделать #privateParam у SomeClass1 неприватным (т.е. убрать #), то getPrivate будет возвращать undefined.
Собственно, вопрос в том, как сделать подобную "фабрику", чтобы она заработала?) Желательно, чтобы и приватные свойства поддерживались, если это, конечно, возможно.