szokodiakos / typegoose

Typegoose - Define Mongoose models using TypeScript classes.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Possible to have Query type support?

kkoomen opened this issue · comments

I have a users service class like so (using NestJS):

import { UpdateQuery, FilterQuery } from 'mongoose';
import { User } from './schemas/users.schema.ts';

class UsersService {
  constructor(@InjectModel(User.name) private readonly usersModel: Model<User>) {}

  async updateOne(
    conditions: FilterQuery<User>,
    fields: UpdateQuery<User>,
    options: Record<string, unknown> = {},
  ): Promise<T> {
    try {
      const result = await this.usersModel.findOneAndUpdate(
        conditions,
        fields,
        { new: true, ...options },
      );
      return result;
    } catch (err) {
      console.log(err);
    }
}

The User schema can look like something like this:

import { Document } from 'mongoose';

class User extends Document {
  username: string;
}

When I have my controller with this:

class MyController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  async update(@Body() body: UpdateUserDTO): Promise<User> {
    // This expression below should cause an error that 'test' does not exists on `User` which doesn't happen.
    return this.usersService.updateOne({ test: true });
  }
}

This can be fixed for some part by modifying the updateOne() in the UsersService like so:

 async updateOne(
    conditions: Partial<Record<keyof User, any>>,
    fields: Partial<Record<keyof User, any>>,
    options: Record<string, unknown> = {},
  ): Promise<T> {
    try {
      const result = await this.usersModel.findOneAndUpdate(
        conditions as FilterQuery<User>,
        fields as UpdateQuery<User>,
        { new: true, ...options },
      );
      return result;
    } catch (err) {
      console.log(err);
    }
  }

but the custom approach above doesn't work for fields named like $addToSet.

The FilterQuery<T>, UpdateQuery<T>, CreateQuery<T> and DeleteQuery<T> (and other similar types) should all check whether the key is keyof T, in my case T is User but mongoose does not do this. Do you perhaps support some kind of solution to this?

this repository and package is not maintained anymore, look at typegoose/typegoose for an continuation