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

javascript - ปัญหา Mongoose loadClass กับ TypeScript


ฉันกำลังใช้ประโยชน์จากสคีมาของคลาส mongoose

และใช้ TypeScript สำหรับโปรเจกต์ Node ของฉัน

ฉันได้ติดตาม Mongoose ในแบบ Typescript ใช่ไหม...? เพื่อให้แน่ใจว่าโมเดลของฉันรับรู้สกีมาที่ฉันกำหนดไว้ ดังนั้นฉันจึงมีการเติมข้อความอัตโนมัติ เป็นต้น

อย่างไรก็ตาม มันจะซับซ้อนมากขึ้นกับคลาสสคีมา ดังที่เขียนไว้ในเอกสารของพวกเขา:

ฟังก์ชัน loadClass() ช่วยให้คุณดึงเมธอด สแตติก และเวอร์ชวลจากคลาส ES6 เมธอดของคลาสจะแมปไปยังเมธอดของสคีมา เมธอดสแตติกจะแมปไปยังสคีมาแบบสแตติก และเก็ตเตอร์/เซ็ตเตอร์จะแมปไปยังเวอร์ชวล

ดังนั้นโค้ดของฉันจึงดูประมาณว่า:

interface IUser extends mongoose.Document {
  firstName: string,
  lastName: string
};

const userSchema = new mongoose.Schema({
  firstName: {type:String, required: true},
  lastName: {type:String, required: true},
});

class UserClass{
   static allUsersStartingWithLetter(letter: string){
       return this.find({...});
   }
   fullName(this: IUser){
      return `${this.firstName} ${this.lastName}`
   }
}
userSchema.loadClass(UserClass);

const User = mongoose.model<IUser>('User', userSchema);
export default User;

เป้าหมายของฉันคือให้ TypeScript เข้าใจว่า:

  1. User มีเมธอด allUsersStartingWithLetter
  2. อินสแตนซ์ User มีเมท็อด fullName

ในการกำหนดค่าปัจจุบัน มันไม่สามารถทำได้ ฉันไม่สามารถทำมันด้วยตัวเอง

คำตอบ #1

คุณพิจารณาเพิ่ม extends mongoose.Model ให้กับ UserClass แล้วหรือยัง?

class UserClass extends mongoose.Model<IUser> {
   static allUsersStartingWithLetter(letter: string){
       return this.find({...});
   }
   fullName(this: IUser){
      return `${this.firstName} ${this.lastName}`
   }
}

คำตอบ #2

คุณ จริงๆ จำเป็นต้องใช้คลาสหรือไม่? คุณสามารถทำสิ่งนี้โดยใช้อินเทอร์เฟซโดยไม่ต้องใช้คลาสได้ นี่คือตัวอย่าง:

/* eslint-disable func-names */
import mongoose from 'mongoose';
export interface Foo {
  id?: string;
  name: string;
  createdAt?: Date;
  updatedAt?: Date;
}

export type FooDocument = mongoose.Document & Foo;

const fooSchema = new mongoose.Schema(
  {
    name: { type: String, required: true },
  },
  { timestamps: true }
);

fooSchema.methods.bar = function (): void {
  const foo = this as FooDocument;
  foo.name = 'bar';
};

const FooModel = mongoose.model<FooDocument>('foos', fooSchema);

export default FooModel;

ด้วยวิธีนี้คุณสามารถใช้ Foo อินเทอร์เฟซสำหรับเมธอดที่มีการพึ่งพาการกลับด้าน ในคลังของคุณมันจะคืนค่า Foo แทนที่จะเป็น FooDocument...

เพิ่มเติม: หากคุณใช้ lean() ในคำขอฐานข้อมูลของคุณ คุณจะได้อินเทอร์เฟซ Foo โดยตรง ข้อมูลเพิ่มเติมเกี่ยวกับ lean อยู่ที่นี่

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