繁体   English   中英

如何在 Typescript 中扩展 Mongoose 架构

[英]How to extend Mongoose Schema in Typescript

我正在制作 3 个模式( articlecommentuser )和共享某些字段的模型。

仅供参考,我正在使用 mongoose 和 typescript。

  • mongoose v6.1.4
  • nodejs v16.13.1
  • typescript v4.4.3

每个 3 模式的接口共享一个公共接口UserContent ,它们看起来像这样:

interface IUserContent {
  slug: string;
  should_show: 'always' | 'never' | 'by_date';
  show_date_from: Date | null;
  show_date_to: Date | null;
  published_date: Date | null;
}

interface IArticle extends IUserContent {
  title: string;
  content: string;
  user_id: number;
}

interface IComment extends IUserContent {
  content: string;
  user_id: number;
}

interface IUser extends IUserContent {
  name: string;
  description: string;
}

我正在尝试制作一个 function 来创建具有共享字段的 Mongoose 架构:

import { Schema, SchemaDefinition } from 'mongoose'

const createUserContentSchema = <T extends object>(fields: SchemaDefinition<T>) => {
  const schema = new Schema<IUserContent & T>({
    // theese fields are shared fields
    slug: { type: String },
    should_show: { type: String, enum: ['always', 'never', 'by_date'] },
    show_date_from: { type: Date },
    show_date_to: { type: Date },
    published_date: { type: Date },

    // this is not-shared fields
    ...fields,
  })
  return schema
}

我预计这个 function 将创建共享字段和非共享字段组合在一起的模式。 (就像下面的代码)

const UserSchema = createUserContentSchema<IUser>({
  name: {type: String},
  description: {type: String},
});

但是,它会在createUserContentSchema function 中的new Schema中的 object 参数上引发类型错误。 (尽管如此编译的 javascript 代码按预期工作)

类型'{蛞蝓:{类型:StringConstructor; }; 应该显示:{类型:StringConstructor; 枚举:字符串[]; }; show_date_from:{类型:DateConstructor; }; show_date_to: {...; }; 发布日期:{...; }; } & SchemaDefinition' 不可分配给类型 'SchemaDefinition<SchemaDefinitionType<IUserContent & T>>'.ts(2345)

我从createUserContentSchema function 中删除了 generic 并直接将T替换为IUser ,结果很好,没有错误。 所以,我保证我在输入泛型时犯了错误。 但无法弄清楚我到底做错了什么。

我想修复我的代码以不产生此类型错误。

附言

我发现我的错误仅在 mongoose@v6(不是 v5)中重现 我阅读了更新说明中的重大更改,但无法弄清楚为什么在 v6 中会产生此错误。

ZCCADCDEDB567ABAE643E15DCF0974E503Z 鉴别器听起来像是您需要的功能。

https://mongoosejs.com/docs/api.html#model_Model.discriminator

function BaseSchema() {
  Schema.apply(this, arguments);

  this.add({
    name: String,
    createdAt: Date
  });
}
util.inherits(BaseSchema, Schema);

const PersonSchema = new BaseSchema();
const BossSchema = new BaseSchema({ department: String });

const Person = mongoose.model('Person', PersonSchema);
const Boss = Person.discriminator('Boss', BossSchema);
new Boss().__t; // "Boss". `__t` is the default `discriminatorKey`

const employeeSchema = new Schema({ boss: ObjectId });
const Employee = Person.discriminator('Employee', employeeSchema, 'staff');
new Employee().__t; // "staff" because of 3rd argument above

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM