Reputation: 31
Is there a way to define a class from the return of a function, and then use that as a property type in an interface?
class Foo {};
function makeFoo<T extends Foo>(classType: T): T {
return classType;
}
const Foo2 = makeFoo(Foo);
new Foo(); // OK
new Foo2(); // OK
interface IFoo {
foo1: Foo; // OK
foo2: Foo2; // 'Foo2' refers to a value, but is being used as a type here.
}
The real world use case is I have a function that adds some static methods to classes using the class's generic types. So,
class DataModel {}
class Foo<T extends DataModel> {}
class Bar extends Foo<DataModel> {
getInstance() {
return 'I am an instance';
}
}
function addStatics<T extends DataModel, TF extends Foo<T>>(
classType: TF,
): TF & { getStatic: () => T } {
return Object.defineProperty(classType, 'getStatic', {
value: () => {},
});
}
// This is: typeof Bar & { getStatic: () => typeof DataModel; }
const BarWithStatics = addStatics(Bar);
console.log(BarWithStatics.getStatic(), new BarWithStatics().getInstance());
In reality it's doing some things with a singleton instance, but yeah, this is the gist of it. I was hoping there was some way to do class BarWithStatics = addStatics(Bar)
but no such luck.
Upvotes: 1
Views: 210
Reputation: 31
Of course as soon as I ask this I figure out the solution. You can extend the return of a function:
class BarWithStatics extends addStatics(Bar) {}
interface IFoo {
bar: BarWithStatics;
}
Upvotes: 1