I am looking to create a function that accepts actual class objects themselves as arguments (within an object containing multiple arguments), with the return type of the function being inferred to be an instance of the class provided as the argument.
In this scenario, we are dealing with an ORM where classes serve as models representing SQL tables. There will be several database query functions (separate from the classes) that will require arguments specifying the table to select data from.
Let's illustrate this concept with some code...
export class DogModelClass {
id:number;
name:string;
woofCount:number;
}
export class CatModelClass {
id:number;
name:string;
meowCount:number;
}
interface ArgumentsInterface {
theActualClass; // <-- referring to the actual CLASS itself, not an instance
}
function getModelFromDatabase(args:ArgumentsInterface) {
// code here retrieves a row for "dog" or "cat" from the DB and returns an INSTANCE of the specified args.theActualClass class
}
// Typescript should infer dogInstance as an INSTANCE of DogModelClass (based solely on the function arguments)...
const dogInstance = getModelFromDatabase({theActualClass:DogModelClass});
// Similarly, typescript should infer catInstance as an INSTANCE of CatModelClass (from the function arguments)...
const catInstance = getModelFromDatabase({theActualClass:CatModelClass});
I understand that I could use generics within the function like so:
function getModelFromDatabaseWithGeneric<ModelGeneric>(args:ArgumentsInterface):ModelGeneric {
return <ModelGeneric>{};
}
const dogInstance2 = getModelFromDatabaseWithGeneric<DogModelClass>({theActualClass:DogModelClass});
However, I prefer not to specify the generic type every time I call the function, since the model class needs to be included in the arguments already for other purposes (such as determining the table to SELECT from). Having to repeat the class name each time I call querying functions seems redundant.
How can I achieve this without explicitly setting the generic type with each function call?
Any suggestions for more precise terminology in relation to passing around "the actual class object - not an instance" in JavaScript would also be appreciated.