Typegoose model find return type?

331 Views Asked by At

I'm using typegoose with strictNullChecks enabled, however when I want to speicfy return type, it never gets right. I have created a base typegoose model and service for others to extend from.
base.model.ts

import { modelOptions, prop } from '@typegoose/typegoose';

@modelOptions({
    schemaOptions: {
        id: false,
        toJSON: {
            getters: true,
            virtuals: true,
            versionKey: false
        }
    }
})
export abstract class BaseModel {
    public _id: string;

    @prop({ index: true, default: Date.now })
    createdAt: Date;

    @prop({ index: true, default: Date.now })
    updatedAt: Date;
}

base.service.ts

import { ReturnModelType } from '@typegoose/typegoose';
import { AnyParamConstructor, DocumentType } from '@typegoose/typegoose/lib/types';
import { FilterQuery, UpdateQuery } from 'mongoose';
import { BaseModel } from './base.model';

export abstract class BaseService<T extends BaseModel> {
    protected model: ReturnModelType<AnyParamConstructor<T>>;

    protected constructor(model: ReturnModelType<AnyParamConstructor<T>>) {
        this.model = model;
    }

    findOne(filter: FilterQuery<T>) {
        return this.model.findOne(filter);
    }

    findAll(filter: FilterQuery<T>) {
        return this.model.find(filter);
    }

    findById(id: string) {
        return this.model.findById(id);
    }

    aggregate() {
        return this.model.aggregate();
    }

    create(item: Partial<T>) {
        return this.model.create(item);
    }

    delete(filter: FilterQuery<T>) {
        return this.model.findOneAndDelete(filter);
    }

    deleteById(id: string) {
        return this.model.findByIdAndDelete(id);
    }

    update(filter: FilterQuery<T>, item: UpdateQuery<DocumentType<T, object>>) {
        return this.model.findOneAndUpdate(filter, item, { new: true });
    }

    updateById(id: string, item: UpdateQuery<DocumentType<T, object>>) {
        return this.model.findByIdAndUpdate(id, item, { new: true });
    }

    count(filter: FilterQuery<T>) {
        return this.model.countDocuments(filter);
    }

    async findOneAsync(filter: FilterQuery<T>): Promise<T> {
        return this.findOne(filter);
    }

    async findAllAsync(filter: FilterQuery<T>) {
        return this.findAll(filter);
    }

    async findByIdAsync(id: string) {
        return this.findById(id);
    }

    async createAsync(item: Partial<T>) {
        return this.create(item);
    }

    async deleteAsync(filter: FilterQuery<T>) {
        return this.delete(filter).exec();
    }

    async deleteByIdAsync(id: string) {
        return this.deleteById(id).exec();
    }

    async updateAsync(filter: FilterQuery<T>, item: UpdateQuery<DocumentType<T, object>>) {
        return this.update(filter, item).exec();
    }

    async updateByIdAsync(id: string, item: UpdateQuery<DocumentType<T, object>>) {
        return await this.updateById(id, item).exec();
    }

    async countAsync(filter: FilterQuery<T>) {
        return await this.count(filter);
    }
}

I want to add the return type Promise<T | null> to functions like findByIdAsync, however it gave me this incredibly long error:

Type 'IfAny<T, any, Document<unknown, BeAnObject, T> & Omit<Require_id<T>, "typegooseName"> & IObjectWithTypegooseFunction> | null' is not assignable to type 'T'.
  'T' could be instantiated with an arbitrary type which could be unrelated to 'IfAny<T, any, Document<unknown, BeAnObject, T> & Omit<Require_id<T>, "typegooseName"> & IObjectWithTypegooseFunction> | null'.

Changing Promise<T> to Promise<DocumentType<T, object>> does not work as well, I don't know what is IfAny at all

0

There are 0 best solutions below