ค้นหาเว็บไซต์

node.js - ฉันจะเพิ่มเมธอดสแตติกให้กับโมเดล Mongoose ใน Typescript สำหรับ Mongoose 5.11 ได้อย่างไร?


ใน 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 วิธีที่ถูกต้องในการเพิ่มเมธอดสแตติกเหล่านี้ให้กับโมเดลของฉันคืออะไร?

คำตอบ #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;

บทความที่เกี่ยวข้อง