【问题标题】:How do I add static methods to Mongoose model in Typescript for Mongoose 5.11?如何在 Typescript for Mongoose 5.11 中向 Mongoose 模型添加静态方法?
【发布时间】:2021-03-18 00:48:00
【问题描述】:

在 Mongoose 5.10 中,我使用以下模式向我的 Mongoose 模型添加静态方法:

import { Schema, Document, Model, Connection } from "mongoose";
import { v4 } from "uuid";

export interface IFoo extends Document {
  id: string;
  name: string;
}

export interface IFooModel extends Model<IFoo> {
  findOneOrCreate({ name }: { name: string }): Promise<IFoo>;
}

const fooSchema = new Schema({
  id: {
    type: String,
    required: true,
    default: () => `a-${v4()}`,
  },
  name: {
    type: String,
    required: true,
    unique: true,
  },
});

fooSchema.static({
  findOneOrCreate: async function (
    this: IFooModel,
    { name }: { name: string }
  ): Promise<IFoo> {
    let foo = await this.findOne({ name });
    if (!foo) {
      foo = await this.create({ name });
    }
    return foo;
  },
});

export default function (db: Connection): IFooModel {
  return db.model<IFoo, IFooModel>("Foo", fooSchema);
}

在 Mongoose 5.11 中,Mongoose 包含了自己的 Typescript 类型定义;覆盖@types/mongoose 中定义的内容。这些更新删除了mongoose.model() 的第二个类型参数,并导致以下类型错误:

src/models/foo.ts:40:3 - error TS2741: Property 'findOneOrCreate' is missing in type 'Model<IFoo>' but required in type 'IFooModel'.

40   return db.model<IFoo, IFooModel>("Foo", fooSchema);
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  src/models/foo.ts:10:3
    10   findOneOrCreate({ name }: { name: string }): Promise<IFoo>;
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    'findOneOrCreate' is declared here.

src/models/foo.ts:40:19 - error TS2558: Expected 1 type arguments, but got 2.

40   return db.model<IFoo, IFooModel>("Foo", fooSchema);
                     ~~~~~~~~~~~~~~~


Found 2 errors.

使用新的 Mongoose 5.11 类型定义,将这些静态方法添加到我的模型的正确方法是什么?

【问题讨论】:

    标签: node.js mongodb typescript mongoose


    【解决方案1】:

    关键是像这样在 Schema 构造函数中设置泛型类型:

    const fooSchema = new Schema<IFoo, IFooModel>({
      id: {
        type: String,
        required: true,
        default: () => `a-${v4()}`,
      },
      name: {
        type: String,
        required: true,
        unique: true,
      },
    });
    

    我也遇到了文档类型不代表返回的模型类型的一些问题,所以我建议创建一个这样的新联合类型,而不是相应地使用您需要的类型:

    export interface IFoo {
      id: string;
      name: string;
    }
    
    type IFooDocument = IFoo & Document;
    

    【讨论】:

      猜你喜欢
      • 2018-01-18
      • 2017-07-15
      • 2013-06-06
      • 2016-01-27
      • 2021-05-24
      • 2020-07-25
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多