Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types for Typescript #51

Open
maxim2muchcoffee opened this issue Dec 7, 2018 · 4 comments
Open

Types for Typescript #51

maxim2muchcoffee opened this issue Dec 7, 2018 · 4 comments

Comments

@maxim2muchcoffee
Copy link

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({})

@limianwang
Copy link

limianwang commented Dec 9, 2018

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. :)

@ExtraBB
Copy link

ExtraBB commented Feb 7, 2019

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 });

@cerinoligutom
Copy link

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 });

@atTheShikhar
Copy link

Almost 3 years still not TypeScript support , sad :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants