I have a function which creates a class using a generic interface. The properties of the instance are set by a parameters of that generic, like this:
const ClassFactory = <T>() => {
class MyClass {
constructor(data: T) {
for (const key in data) {
if (!data.hasOwnProperty(key)) { continue; }
(this as any)[key] = data[key];
}
}
// other methods can be here
}
return MyClass;
}
const GeneratedClass = ClassFactory<{ id: number }>();
const myInstance = new GeneratedClass({ id: 1 });
console.log((myInstance as any).id); // logs 1
This runs as intended, however there are 2 problems
myInstancetypings doesn't have the keys of T - I'm expectingmyInstance.idto be a number- I have to cast
this as anyin the constructor to assign the values by the given data
In an attempt to fix the first problem I've tried various things I've seen from other posts, including
class MyClass implements T, but they all result in the same error: A class can only implement an object type or intersection of object types with statically known members.ts(2422).
I understand why it happens, however since T is known when defining the Class, is there a way for this to work?
If I have the data in a public data: T property, then myInstance.data.id is properly typed. So my question is, can this be done by skipping the .data part?
Thanks in advance
javascripttag though ?return MyClass as { new(): T }.return MyClass as { new(data: T): T };it's working properly for the example above, however if there is any method in the class it fails. Ideally it would just override thenew, not the entire class.