Нужно сделать функцию, которая будет возвращать расширенный класс, унаследованный от переданного в аргумент класса.
Например: Есть класс Collection, который принимает T в качестве хранимого типа.
нужно сделать функции:
extendAny - Расширяет любой переданный в нее ЛЮБОЙ класс
extendSpecific - Расширяет СПЕЦИФИЧНЫЙ класс.
По итогу, хочется видеть класс, который является наследником всех вызванных функций и аргументов этих функций. Соответственно обладает их св-ми, и принимает тип переданный в класс.
type Constructor<T = any> = new (...args: any[]) => T;
interface ITest {
n: number;
s: string;
}
class Collection<T> {
_items: T[] = [];
myPush(item: T) {
this._items.push(item);
}
}
function extendAny <T extends Constructor>(target: T) {
class ExtendAny extends target {
_isExtendedAny = true;
get isExtendedAny() {
return this._isExtendedAny;
}
}
return ExtendAny as T & Constructor<ExtendAny>;
}
function extendSpecific <U, T extends Constructor<Collection<U>>>(target:T) {
class ExtendSpecific extends target {
_isExtendedSpecific = true;
get isExtendedSpecific() {
return this._isExtendedSpecific;
}
someMethod(arg: U) {
this.myPush(arg);
}
}
return ExtendSpecific as Constructor<ExtendSpecific> & T;
}
class TestObject extends extendSpecific<ITest>(extendAny(Collection<ITest>)) {
_testProp = 'test-prop';
};
const instance = new TestObject();
instance.someMethod({ i: 1 });
TS не ругается на последний вызов метода someMethod, а должен, так как someMethod должен принимать аргумент типа ITest;