Skip to content

Instantly share code, notes, and snippets.

@WangHansen
Last active October 14, 2022 18:40
Show Gist options
  • Save WangHansen/f23f70b758bb9f38fc68414c809e765f to your computer and use it in GitHub Desktop.
Save WangHansen/f23f70b758bb9f38fc68414c809e765f to your computer and use it in GitHub Desktop.
Convert Mongoose js to ts
import { Document, Model, model, Types, Schema, Query } from "mongoose"
import { Company } from "./Company"
// Schema
const UserSchema = Schema<UserDocument, UserModel>({
firstName: {
type: String,
required: true
},
lastName: String,
username: {
type: String,
unique: true,
required: true,
lowercase: true
},
password: {
type: String,
required: true
},
company: {
type: Schema.Types.ObjectId,
ref: "Company",
required: true
},
gender: {
type: Number,
enum: [0, 1],
default: 0,
required: true
},
friends: [{
type: String,
}],
creditCards: {
type: Map,
of: string
}
})
enum Gender {
Male = 1,
Female = 0
}
export interface User {
firstName: string;
lastName?: string;
username: string;
password: string;
company: Types.ObjectId | Record<string, unknown>;
gender: Gender;
friends: Array<string>;
creditCards?: Map<string, string>;
}
/**
* Not directly exported because it is not recommanded to
* use this interface direct unless necessary since the
* type of `company` field is not deterministic
*/
interface UserBaseDocument extends User, Document {
friends: Types.Array<string>;
creditCards?: Types.Map<string>;
fullName: string;
getGender(): string;
}
// Export this for strong typing
export interface UserDocument extends UserBaseDocument {
company: Company["_id"];
}
// Export this for strong typing
export interface UserPopulatedDocument extends UserBaseDocument {
company: Company;
}
// Virtuals
UserSchema.virtual("fullName").get(function(this: UserBaseDocument) {
return this.firstName + this.lastName
})
// Methods
UserSchema.methods.getGender = function(this: UserBaseDocument) {
return this.gender > 0 ? "Male" : "Female"
}
// For model
export interface UserModel extends Model<UserDocument> {
findMyCompany(id: string): Promise<UserPopulatedDocument>
}
// Static methods
UserSchema.statics.findMyCompany = async function(
this: Model<UserDocument>,
id: string
) {
return this.findById(id).populate("company").exec()
}
// Document middlewares
UserSchema.pre<UserDocument>("save", function(next) {
if (this.isModified("password")) {
this.password = hashPassword(this.password)
}
});
// Query middlewares
UserSchema.post<Query<UserDocument, UserDocument>>("findOneAndUpdate", async function(doc) {
await updateCompanyReference(doc);
});
// Default export
export default model<UserDocument, UserModel>("User", UserSchema)
@polRk
Copy link

polRk commented May 4, 2021

Where i can find "./Company"

@WangHansen
Copy link
Author

I just assumed there is another schema named Company to demonstrate the relationship, it doesn't actually exist in this example and it could be anything

@polRk
Copy link

polRk commented May 4, 2021

Is it Document?

@WangHansen
Copy link
Author

Is it Document?

It's another Schema

@polRk
Copy link

polRk commented May 4, 2021

Like UserShema, or User?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment