mongo-cursor-pagination
mongo-cursor-pagination copied to clipboard
Types for Typescript
Hi guys! It's a good plugin to use with mongoose. The only thing I'm missing is support for TypeScript types. For example TypeScript doesn't know what is .paginate() in such expression: this.questionModel.paginate({})
I agree. Being new to ts as well made it a bit of a challenge. But I did some stack overflow research and one of them led to this:
declare module 'mongoose' {
export interface IPaginateOptions {
query: Object;
limit?: number;
next?: string;
}
export interface PaginateResult<T> {
results: Array<T>;
next: string;
}
export interface IPaginateModel<T extends Document> extends Model<T> {
paginate(options: IPaginateOptions): Promise<PaginateResult<T>>;
}
export function model<T extends Document>(
name: string,
schema?: Schema,
collection?: string,
skipInit?: boolean,
): IPaginateModel<T>;
export function model<T extends Document, U extends IPaginateModel<T>>(
name: string,
schema?: Schema,
collection?: string,
skipInit?: boolean,
): U;
}
declare module "mongo-cursor-pagination" {
import mongoose from 'mongoose';
export function mongoosePlugin(schema: mongoose.Schema): void;
}
I don't think it's perfect though. Just something that got it working. I definitely would appreciate if any advanced TS folks can help to sort out the typedef for mongo-cursor-pagination
. :)
For any of you that are using Typegoose, I created the following:
import { Model, DocumentQuery } from "mongoose";
import { InstanceType } from "typegoose";
export interface IPaginateOptions {
query?: Object;
limit?: number;
fields?: Object;
paginatedField?: string;
sortAscending?: Boolean;
next?: string;
previous?: string;
}
export interface IPaginateResult<T> {
hasNext: boolean;
hasPrevious: boolean;
next?: string;
previous?: string;
results: T[];
}
export interface IPaginateModel<T> extends Model<InstanceType<T>> {
paginate(options: IPaginateOptions): DocumentQuery<IPaginateResult<T>, InstanceType<T>>;
}
and export your typegoose model as follows:
export const UserModel = new User().getModelForClass(User) as IPaginateModel<InstanceType<User>> & User & typeof User;
Now you can use paginate()
anywhere as you would find()
:
const query = {}; // The query that you would normally use
const users = await UserModel.paginate({ query: query, limit: 10, paginatedField: "email", sortAscending: true });
Building on top of @ExtraBB's answer w/ Typegoose v7.2.0 and Mongoose 5.9.20 as of writing.
I created a BaseModelSchema
class which has a static paginate()
function to be inherited by other domain-specific schema.
import { plugin, defaultClasses, DocumentType } from '@typegoose/typegoose';
import { DocumentQuery } from 'mongoose';
const MongoCursorPagination = require('mongo-cursor-pagination');
@plugin(MongoCursorPagination.mongoosePlugin) // https://github.com/mixmaxhq/mongo-cursor-pagination#with-mongoose
export class BaseModelSchema extends defaultClasses.Base {
get id(): string {
return this._id.toHexString();
}
static paginate<T>(this: T, options: IPaginateOptions): DocumentQuery<IPaginateResult<T>, DocumentType<T>> {
return (this as any).paginate(options);
}
}
interface IPaginateOptions {
query?: object;
limit?: number;
fields?: object;
paginatedField?: string;
sortAscending?: boolean;
next?: string;
previous?: string;
}
interface IPaginateResult<T> {
hasNext: boolean;
hasPrevious: boolean;
next?: string;
previous?: string;
results: T[];
}
Then usage:
class UserModelSchema extends BaseModelSchema {
// your custom props
}
const UserModel = getModelForClass(UserModelSchema);
const users = await UserModel.paginate({ query: query, limit: 10, paginatedField: "email", sortAscending: true });
Almost 3 years still not TypeScript support , sad :(