【问题标题】:How to extend Mongoose Schema in Typescript如何在 Typescript 中扩展 Mongoose Schema
【发布时间】:2021-12-20 19:15:21
【问题描述】:

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

仅供参考,我正在使用猫鼬和打字稿。

  • 猫鼬 v6.1.4
  • nodejs v16.13.1
  • 打字稿 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;
}

我正在尝试创建一个函数来创建具有共享字段的 Mongoose Schema:

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
}

我预计此函数将创建包含共享字段和非共享字段组合在一起的架构。 (如下代码)

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

但是,它会在new Schema 中的对象参数上引发类型错误,该参数位于createUserContentSchema 函数内。 (不过编译后的 javascript 代码运行良好)

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

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

我想修复我的代码以不出现此类型错误。

PS

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

【问题讨论】:

  • 无法重现您的问题。见codesandbox.io/s/…
  • @slideshowp2 我根据您的代码框进行了额外的测试,发现我的错误在 mongoose v6 中重现。我可以保证这仅仅是因为新版本的猫鼬中有一些错误吗?等到人们修复它?

标签: node.js typescript mongodb mongoose


【解决方案1】:

Mongoose Discriminator 听起来像是您需要的功能。

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

【讨论】:

  • 这不适用于 Typescript。
猜你喜欢
  • 2012-12-25
  • 2021-08-20
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
相关资源
最近更新 更多