What is mongoose-paginate-v2?
mongoose-paginate-v2 is a pagination library for mongoose. With mongoose-paginate-v2, you can fetch a list of documents from a MongoDB collection and get a paginated response.
Paginated responses are useful for cases where UI clients needs to query and display only a section of data at a time.

UI Table Pagination - ui.shadcn.com
The mongoose-paginate-v2 documentation provides a code snippet for how to use the library with TypeScript. 1
Setting the type of docs items
Prior to version 1.7.4 of mongoose-paginate-v2, it was not possible to set the
type of the items in docs. The type of the items in docs was set to the type
passed in when the mongoose model was created.
import { model, PaginateModel, Schema, Types } from "mongoose";
import paginate from 'mongoose-paginate-v2';
// Create the model interface
interface Person {
_id: Types.ObjectId
name: string
birthYear: number
favouriteFood: string
}
// Create the schema
const personSchema = new mongoose.Schema({
name: String;
birthYear: Number;
favouriteFood: String;
});
// attach the mongoose-paginate-v2 plugin
personSchema.plugin(paginate);
// create the paginated model
// PaginateModel<Person> sets the type of docs items to Person
const PersonModel = model<Person, PaginateModel<Person>>('Person', personSchema);
// Create documents
await PersonModel.create([
{
name: "John Doe",
birthYear: 1970
favouriteFood: "Bacon"
},
{
name: "Jane Doe"
birthYear: 1970
favouriteFood: "French fries"
}
])
// Get a paginated list of documents
const { docs, totalDocs, page, prevPage, nextPage, totalPages } =
await Business.paginate(
{},
{
offset: 1,
limit: 1,
}
);
In the example above, the items in the docs array are typed to Person,
and docs will have a type of Person[]. Everything is fine until you use the
select,
the
populate
or the other mongoose options that change the output like
projection
and fields.
const { docs, totalDocs, page, prevPage, nextPage, totalPages } =
await Business.paginate(
{},
{
select: "-favouriteFood",
offset: 1,
limit: 1,
}
);
In the code snippet above, we exclude the favouriteFood field from the items
in the docs fields returned. In other words, the type of docs should be an
array of
{
_id: Types.ObjectId;
name: string;
birthYear: number;
}
but it is not so. docs is typed to Person[] with all the fields included,
which can be deceiving.
Setting Custom Types for docs Items
mongoose-paginate-v2 version 1.7.4 now provides an option that can be used to
dynamically set the type of docs items.
Setting the type of the items returned in the docs array can be done in either
of two ways:
- Passing the desired type as the first argument to the
paginategeneric - Passing the desired type as the second argument to the
paginategeneric
Passing the desired type as the first argument to the paginate generic
type PersonWithoutFavouriteFood = {
_id: Types.ObjectId;
name: string;
birthYear: number;
};
const { docs, totalDocs, page, prevPage, nextPage, totalPages } =
await Business.paginate<PersonWithoutFavouriteFood>(
{},
{
select: "-favouriteFood",
offset: 1,
limit: 1,
}
);
You can use this method if you do not want to modify the type of the options
passed in as the second argument to the paginate function.
Passing the desired type as the second argument to the paginate generic
import { PaginateOptions } from "mongoose";
type PersonWithoutFavouriteFood = {
_id: Types.ObjectId;
name: string;
birthYear: number;
};
const { docs, totalDocs, page, prevPage, nextPage, totalPages } =
await Business.paginate<PaginateOptions, PersonWithoutFavouriteFood>(
{},
{
select: "-favouriteFood",
offset: 1,
limit: 1,
}
);
You can use this method if you want to modify the type of the options passed in
as the second argument to the paginate function. The type is PaginateOptions
by default.
Shameless plug - I authored this feature.
