I am creating a database schema which requires a string name of each model type and I need to avoid using classes. My database models are defined by an enum and interfaces:
const enum Models {
Person = 'Person',
Vehicle = 'Vehicle',
}
export interface Person {
firstname: string;
lastname?: string;
}
export interface Vehicle {
model: string;
year?: string;
}
The DatabaseModel interface links the modelType name and associated data:
export interface DatabaseModel {
modelType: any;
data: any;
}
This type maps the interface to a specific enum. I am not sure how to use this exactly, but I think it is needed for type checking to work correctly.
export type ModelInterfaceMap = {
Person: Person;
Vehicle: Vehicle;
}
I have created a function which creates a DatabaseModel as follows:
export function create(modelType: Models, data ): DatabaseModel {
return {
modelType,
data,
};
}
My question is, how do I add typings to the above code so that I can call the create function and only reference the model type once in the first modelType parameter and still get all the benefits of type checking the data against it's associated model?
This should pass type checking
var newPerson = create(Models.Person, { firstname: 'John', lastname: 'Doe' });
var newVehicle = create(Models.Vehicle, { model: 'Ford', year: '2018' });
This should fail type checking because the Person interface does not have a year
var newPersonFail = create(Models.Person, { firstname: 'John', lastname: 'Doe', year: '2018' });
I tried using generic types like this, but this requires writing the model type twice; once in the generic type and once when passing in the modelType. I would like to avoid having to specify the modelType twice.
export function create<T>(modelType: Models, data : <T> ): DatabaseModel<T> {...}