Node + Mongoose + TypeScript: Defining Schemas and Models

Last updated on July 12, 2022 Augustus 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 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 interfaces representing documents
  2. Define schemas corresponding to the document interfaces
  3. Create models

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 it a more complex thing. Change some lines of code and see what happens.

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