首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新的Typegoose抽象

更新的Typegoose抽象
EN

Stack Overflow用户
提问于 2021-05-11 19:05:50
回答 1查看 245关注 0票数 0

我最近一直在研究NestJS,并开始了一些示例项目。这个项目使用MongoDB,所以我也选择了Typegoose来实现这一点。我在网上找到了一个教程(https://nartc.netlify.app/blogs/nestjs-typegoose/),它描述了如何在基本typegoose模型中使用一些抽象。

所以,我的base.service.ts现在看起来像这样:

代码语言:javascript
复制
import { InternalServerErrorException } from '@nestjs/common';
import { DocumentType, ReturnModelType } from '@typegoose/typegoose';
import { AnyParamConstructor } from '@typegoose/typegoose/lib/types';
import { MongoError } from 'mongodb';
import { DocumentQuery, Types, Query, UpdateQuery } from 'mongoose';

import { BaseModel } from './base.model';

type QueryList<T extends BaseModel> = DocumentQuery<
  Array<DocumentType<T>>,
  DocumentType<T>
>;
type QueryItem<T extends BaseModel> = DocumentQuery<
  DocumentType<T>,
  DocumentType<T>
>;

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

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

  protected static throwMongoError(err: MongoError): void {
    throw new InternalServerErrorException(err, err.errmsg);
  }

  protected static toObjectId(id: string): Types.ObjectId {
    try {
      return Types.ObjectId(id);
    } catch (e) {
      this.throwMongoError(e);
    }
  }

  createModel(doc?: Partial<T>): T {
    return new this.model(doc);
  }

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

  async findAllAsync(filter = {}): Promise<Array<DocumentType<T>>> {
    try {
      return await this.findAll(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

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

  async findOneAsync(filter = {}): Promise<DocumentType<T>> {
    try {
      return await this.findOne(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  findById(id: string): QueryItem<T> {
    return this.model.findById(BaseService.toObjectId(id));
  }

  async findByIdAsync(id: string): Promise<DocumentType<T>> {
    try {
      return await this.findById(id).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  async create(item: T): Promise<DocumentType<T>> {
    try {
      return await this.model.create(item);
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

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

  async deleteAsync(filter = {}): Promise<DocumentType<T>> {
    try {
      return await this.delete(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  deleteById(id: string): QueryItem<T> {
    return this.model.findByIdAndDelete(BaseService.toObjectId(id));
  }

  async deleteByIdAsync(id: string): Promise<DocumentType<T>> {
    try {
      return await this.deleteById(id).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  update(item: T): QueryItem<T> {
    return this.model.findByIdAndUpdate(BaseService.toObjectId(item.id), item, {
      new: true
    });
  }

  async updateAsync(item: T): Promise<DocumentType<T>> {
    try {
      return await this.update(item).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  count(filter = {}): Query<number> {
    return this.model.count(filter);
  }

  async countAsync(filter = {}): Promise<number> {
    try {
      return await this.count(filter);
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }
}

这是上面提到的博客文章中的完全相同的代码。然而,我得到了一些错误:

代码语言:javascript
复制
No overload matches this call.
  The last overload gave the following error.
    Argument of type 'T' is not assignable to parameter of type 'UpdateQuery<DocumentType<T>>'.
      Type 'BaseModel' is not assignable to type 'UpdateQuery<DocumentType<T>>'.
        Type 'BaseModel' is not assignable to type '_UpdateQuery<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & DotAndArrayNotation<...>'.
          Type 'BaseModel' is not assignable to type 'ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>>'.
            Type 'T' is not assignable to type '_UpdateQuery<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & DotAndArrayNotation<...>'.
              Type 'BaseModel' is not assignable to type '_UpdateQuery<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>> & DotAndArrayNotation<...>'.
                Type 'BaseModel' is not assignable to type 'ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>>'.
                  Type 'T' is not assignable to type 'ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>>'.
                    Type 'BaseModel' is not assignable to type 'ReadonlyPartial<_AllowStringsForIds<LeanDocument<DocumentType<T>>>>'.

这个错误指向update方法,this.model.findByIdAndUpdate(BaseService.toObjectId(item.id), item, ...);内部的item参数我知道item的类型是<T extends BaseModel>,它在博客文章上有效,但是为什么我在这里得到了一个错误?

此外,还会出现以下错误:

代码语言:javascript
复制
Generic type 'Query<ResultType, DocType, THelpers>' requires between 2 and 3 type arguments.

Query<number>中的count方法上。

我不明白的一件事是,为什么这些错误会出现在我的项目中,而不是出现在前面提到的教程中?

EN

回答 1

Stack Overflow用户

发布于 2021-05-11 20:35:27

此错误似乎是您安装了非官方和官方类型,或者非官方类型与typegoose不兼容

非官方类型是@types/mongoose

官方类型是从mongoose 5.10.19开始提供的(但仅在~5.11.18之后有效)

typegoose 8.0.0-beta.x目前只支持官方类型,typegoose这是look here on which versions in the beta are supported分支

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67485507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档