TypeScript Support
Mongoose introduced officially supported TypeScript bindings in v5.11.0. Mongoose’s index.d.ts
file supports a wide variety of syntaxes and strives to be compatible with @types/mongoose
where possible. This guide describes Mongoose’s recommended approach to working with Mongoose in TypeScript.
Creating Your First Document
To get started with Mongoose in TypeScript, you need to:
- Create an interface representing a document in MongoDB.
- Create a Schema corresponding to the document interface.
- Create a Model.
- Connect to MongoDB.
import { Schema, model, connect } from 'mongoose';
// 1. Create an interface representing a document in MongoDB.
interface User {
name: string;
email: string;
avatar?: string;
}
// 2. Create a Schema corresponding to the document interface.
const schema = new Schema<User>({
name: { type: String, required: true },
email: { type: String, required: true },
avatar: String
});
// 3. Create a Model.
const UserModel = model<User>('User', schema);
run().catch(err => console.log(err));
async function run(): Promise<void> {
// 4. Connect to MongoDB
await connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const doc = new UserModel({
name: 'Bill',
email: 'bill@initech.com',
avatar: 'https://i.imgur.com/dM7Thhn.png'
});
await doc.save();
console.log(doc.email); // 'bill@initech.com'
}
You as the developer are responsible for ensuring that your document interface lines up with your Mongoose schema. For example, Mongoose won’t report an error if email
is required
in your Mongoose schema but optional in your document interface.
Using extends Document
Alternatively, your document interface can extend Mongoose’s Document
class. Many Mongoose TypeScript codebases use the below approach.
import { Document, Schema, model, connect } from 'mongoose';
interface User extends Document {
name: string;
email: string;
avatar?: string;
}
This approach works, but we recommend your document interface not extend Document
. Using extends Document
makes it difficult for Mongoose to infer which properties are present on query filters, lean documents, and other cases.
We recommend your document interface contain the properties defined in your schema and line up with what your documents look like in MongoDB. Although you can add instance methods to your document interface, we do not recommend doing so.
Using Custom Bindings
If Mongoose’s built-in index.d.ts
file does not work for you, you can remove it in a postinstall script in your package.json
as shown below. However, before you do, please open an issue on Mongoose’s GitHub page and describe the issue you’re experiencing.
{
"postinstall": "rm ./node_modules/mongoose/index.d.ts"
}
Next Up
Now that you’ve seen the basics of how to use Mongoose in TypeScript, let’s take a look at statics in TypeScript.