如何使用带Typescript的Mongoose实现强类型的静态模式功能?

时间:2019-07-17 19:49:35

标签: node.js mongodb typescript mongoose

我想知道使用TypeScript时为Mongoose Schema实现强类型静态函数的最佳方法是什么。

我现在有一个解决方案,但是感觉很混乱,并且如果必须为每个架构完成的话会添加很多额外的代码。我将在这篇文章的底部介绍它,但将首先显示当前设置:

我有以下界面:

interfaces/Player.ts

export interface Player {
  name: string
  password: string
}

export interface PlayerDocument extends Player, Document {
   // statics
   findByName(name: string): any
};

我在这里有两个界面的原因是因为我希望能够在没有Mongoose绑定以及应用程序其他位置的情况下使用Player界面。这里的PlayerDocument表示架构就绪的接口,我们将在这里使用它:

schemas/Player.ts


const playerSchema = new mongoose.Schema({
  name:  { type: String, required: true, unique: true },
  password: String,
});

// Not using arrow functions because they prevent binding this. 
// See mongoose-docs
playerSchema.statics.findByName = function(name: string) {
  return this.find({ name: new RegExp(name, 'i') });
}

interface test {
  findByName(name: string): any
}

export default mongoose.model<PlayerDocument>('Player', playerSchema);

这里的问题是,每当我现在在应用程序的其他位置使用架构时,类型中都不会出现静态函数findByName(name: string): any

app.ts

import PlayerSchema from './schemas/Player';
const test = async () => {
    const x = await PlayerSchema.findByName('Erlend');
    console.log(x);
}

这给出了:

code hint not appearing

我的解决方案,似乎很黑

我设法通过创建以下组合类型来解决此问题:

schemas/Player.ts

interface test {
    findByName(name: string): any
}
type something = mongoose.Model<PlayerDocument> & test;
export default (mongoose.model<PlayerDocument>('Player', playerSchema)) as something;

最后,

code hint appearing

但是如上所述,我觉得应该有一个更好的方法。

1 个答案:

答案 0 :(得分:1)

将您的模型键入界面:

export interface Player {
  name: string;
  password: string;
}

export interface PlayerModel extends Model<Player & Document> {
   findByName: (name: string) => any;
}

现在,当您创建模型时,请给它两种类型:文档和模型:

const playerModel = model<Player, PlayerStatics>('Player', playerSchema);

playerModel.findByName('foo');

另请参阅: