Node + Mongoose + TypeScript: Defining Schemas and Models

Last updated on October 19, 2021 Pennywise Loading... Post a comment

This article walks you through a concise and straight-to-the-point example of declaring schemas and defining models with Mongoose and TypeScript. Without any further ado (e.g, talking about the history of Node.js or explaining what MongoDB is or why you should use Mongoose), let’s get our hands dirty and write some code.

Overview

We will work with a database that is used for a blog. It simply contains 2 collections:

  • users: stores users’ information
  • posts: stores blog posts. Each post references to a certain user. A single user can own multiple posts.

In general, when using Mongoose with TypeScript, we will follow the steps below:

  1. Declare an interface representing a document
  2. Define a schema corresponding to the document interface
  3. Create a model

The Code

User Model

Create a file named user.model.ts (the name is totally up to you) and add the following:

// user.model.ts
import { Document, Schema, model } from 'mongoose';

// Create the interface
export interface IUser extends Document {
  firstName: string;
  lastName: string;
  email: string;
  password: string;
  photo?: string;
  birthday?: Date;
}

// Create the schema
const UserSchema = new Schema<IUser>({
  firstName: {
    type: String,
    required: true
  },
  lastName: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  photo: String,
  birthday: String
}, {
  timestamps: {
    createdAt: 'createdAt',
    updatedAt: "updatedAt"
  }
});

// Create and export user model
export const UserModel = model<IUser>("User", UserSchema);

Post Model

Create a new file named post.model.ts in the same directory where user.model.ts resides. We will reference each post with a specific _id of a user. The correct type for the user ref field is mongoose.Schema.Types.ObjectId (the type for user when defining the post interface should be Types.ObjectId).

import { Document, Schema, Types, model } from 'mongoose';

// post interface
export interface IPost extends Document {
  title: string;
  content: string;
  thumbnail?: string;
  status: "draft" | "published" | "trashed";
  views: number;
  user: Types.ObjectId;
}

// post schema
const PostSchema = new Schema<IPost>({
  title: {
    type: String,
    required: true
  },
  content: {
    type: String,
    required: true
  },
  thumbnail: String,
  status: {
    type: String,
    enum: ["draft", "published", "trashed"],
    default: "draft"
  },
  views: {
    type: Number,
    default: 0
  },
  user: {
    type: Schema.Types.ObjectId, 
    ref: "User",
    required: true,
  }
}, {
  timestamps: {
    createdAt: 'createdAt',
    updatedAt: "updatedAt"
  }
})

// create and export post model
export const PostModel = model<IPost>("Post", PostSchema);

Afterword

You’ve learned the fundamentals of using Node.js with TypeScript and Mongoose. From now on, you can extend the example above and make a more complex thing. If you’d like to explore more new and exciting stuff about modern Node.js, take a look at the following articles:

You can also check out our Node.js category page for the latest tutorials and examples.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Related Articles