我想知道使用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);
}
这给出了:
我设法通过创建以下组合类型来解决此问题:
schemas/Player.ts
interface test {
findByName(name: string): any
}
type something = mongoose.Model<PlayerDocument> & test;
export default (mongoose.model<PlayerDocument>('Player', playerSchema)) as something;
最后,
但是如上所述,我觉得应该有一个更好的方法。
答案 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');
另请参阅: