I'm a newbie to TypeScript.
I've been looking to find elegant patterns to define Mongoose schemas using TypeScript. I've been studying an article by Nicholas Mordecai at:
https://know-thy-code.com/mongoose-schemas-models-typescript/
It's a very helpful (thanks Nicholas)! There are though a few coding conventions I just can't get to the bottom of. The first relates to the following chunk of code ...
import { Schema, model, Document, Model } from 'mongoose';
declare interface IContact extends Document{
name: string;
email: string;
phone?: string;
message?: string;
course_enquiry?: string;
creation_date: Date;
}
export interface ContactModel extends Model<IContact> {};
The specific bit that's confusing me is:
"Model<IContact> {};"
Of course, I can't even look at the generated js code because interfaces don't get transpiled.
ContactModel extends IContact, but only after IContact has been re-asserted/cast (from a Mongoose Document) to a Mongoose Model. Have I assumed correctly here? What's stumping me is simply what the code convention ...
"Class<interface> {};"
actually does/achieves!
The second question relates to the following piece of code, which Nicholas has contained within the same ts file as the above:
export class Contact {
private _model: Model<IContact>;
constructor() {
const schema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true },
phone: { type: String },
message: { type: String },
course_enquiry: { type: String },
creation_date: { type: Date, default: Date.now }
});
this._model = model<IContact>('User', schema);
}
public get model(): Model<IContact> {
return this._model
}
}
The bit I would appreciate help on in here is the assessor get method...
public get model(): Model<IContact> {
return this._model
}
I understand the principle of get assessors but I'm not sure whether the code after "model():" is returning a function or an instance of this._model (or both)?
Also, in a separate ts controller file, Nicholas uses the following two pieces of code to use the above...
import { connect, connection, Connection } from 'mongoose';
import { Contact, ContactModel } from './../models/contactsModel';
declare interface IModels {
Contact: ContactModel;
}
this._models = {
Contact: new Contact().model
// this is where we initialise all models
}
NB. this._models is defined as "private _models: IModels;"
I'd really love to understand specifically and in detail what this code is doing! My interpretation is that a new Contact object is being created, which then uses the get assessor method model(), which returns an IContact interface (cast/asserted as a Model)??
Any help greatly appreciated!!
Many thanks.
In
Model<IContact>
, you are seeing a Generic Class. See the Docs about them here.