使用 Mongoose 和 Typescript,接口的 ref 字段应该使用什么类型?

And*_*e M 8 javascript mongoose

我正在使用 mongoose 和 Typescript,我想知道在创建接口时我应该使用什么类型作为参考字段?考虑以下两个相关接口:

interface ICat {
  name: string,
  colour: string,
}

interface ICatDB extends ICat, Document {};

Run Code Online (Sandbox Code Playgroud)
interface IMouse {
  name: string,
  colour: string,
  chasedBy: /* ... */
}

interface IMouseDB extends IMouse, Document {};
Run Code Online (Sandbox Code Playgroud)

以及使用它们的模式和模型:

let cat = new Schema({
  name: String,
  colour: String,
});

mongoose.model<ICatDB>('Cat', cat);
Run Code Online (Sandbox Code Playgroud)
let mouse = new Schema({
  name: String,
  colour: String,
  chasedBy: { type: Schema.Types.ObjectId, ref: 'Cat' }
});

mongoose.model<IMouseDB>('Mouse', mouse);

Run Code Online (Sandbox Code Playgroud)

对于该chasedBy字段,我们需要考虑它可以采用三种形式的值:

  • String或者ObjectId,当传递给create()方法时
  • ObjectId从猫鼬返回时
  • 从 Mongoose 返回时的实例ICat,使用populate()

有没有一种方法可以让我们指定接口可以支持的类型,而不必求助于 using any

顺便说一句,我们将IMouse和分开,因为 Typescript 希望每次创建新对象时都填写IMouseDB所有字段,所以这是一个解决方法。DocumentIMouse

ya_*_*mon 8

至少对于 5.x 版本,您可以使用此: https://mongoosejs.com/docs/5.x/docs/typescript/populate.html

import { PopulatedDoc } from 'mongoose';
import ICat from './ICat';

interface IMouse {
  name: string,
  colour: string,
  chasedBy: PopulatedDoc<ICat>
}
Run Code Online (Sandbox Code Playgroud)

6.x 中的文档显示了不同的方法: https:
//mongoosejs.com/docs/typescript/populate.html
,如下所示:

MouseModel.findOne({}).populate<{chasedBy: ICat}>('chasedBy');
Run Code Online (Sandbox Code Playgroud)


And*_*e M 2

由于缺乏任何替代答案,我选择了:

import { ObjectID } from 'mongodb';
import ICat from './ICat';

interface IMouse {
  name: string,
  colour: string,
  chasedBy: string | ObjectID | ICat
}
Run Code Online (Sandbox Code Playgroud)

这描述了“chasedBy”属性的类型变体。至于这是否是推荐的方法,我不能说。