Skip to content

Instantly share code, notes, and snippets.

@WangHansen
Last active October 14, 2022 18:40
Show Gist options
  • Select an option

  • Save WangHansen/f23f70b758bb9f38fc68414c809e765f to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

polRk commented May 4, 2021

Where i can find "./Company"

@WangHansen
Copy link
Copy Markdown
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
Copy Markdown

polRk commented May 4, 2021

Is it Document?

@WangHansen
Copy link
Copy Markdown
Author

Is it Document?

It's another Schema

@polRk
Copy link
Copy Markdown

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