在 TypeScript 中的靜態方法和實例方法
您可以在 Mongoose 模型上定義實例方法和靜態函式。透過一些額外的設定,您也可以在 TypeScript 中註冊方法和靜態函式。
實例方法
若要在 TypeScript 中定義實例方法,請建立一個新的介面,代表您的實例方法。您需要將該介面作為 Schema
建構子的第三個泛型參數,並且作為 Model
的第三個泛型參數傳遞,如下所示。
import { Model, Schema, model } from 'mongoose';
interface IUser {
firstName: string;
lastName: string;
}
// Put all user instance methods in this interface:
interface IUserMethods {
fullName(): string;
}
// Create a new Model type that knows about IUserMethods...
type UserModel = Model<IUser, {}, IUserMethods>;
// And a schema that knows about IUserMethods
const schema = new Schema<IUser, UserModel, IUserMethods>({
firstName: { type: String, required: true },
lastName: { type: String, required: true }
});
schema.method('fullName', function fullName() {
return this.firstName + ' ' + this.lastName;
});
const User = model<IUser, UserModel>('User', schema);
const user = new User({ firstName: 'Jean-Luc', lastName: 'Picard' });
const fullName: string = user.fullName(); // 'Jean-Luc Picard'
靜態方法
Mongoose 模型對於靜態方法沒有明確的泛型參數。如果您的模型有靜態方法,我們建議建立一個介面,擴展 Mongoose 的 Model
介面,如下所示。
import { Model, Schema, model } from 'mongoose';
interface IUser {
name: string;
}
interface UserModel extends Model<IUser> {
myStaticMethod(): number;
}
const schema = new Schema<IUser, UserModel>({ name: String });
schema.static('myStaticMethod', function myStaticMethod() {
return 42;
});
const User = model<IUser, UserModel>('User', schema);
const answer: number = User.myStaticMethod(); // 42
Mongoose 現在支援自動類型化的靜態函式,它已在模式選項中提供。靜態函式可以定義如下
import { Schema, model } from 'mongoose';
const schema = new Schema(
{ name: String },
{
statics: {
myStaticMethod() {
return 42;
}
}
}
);
const User = model('User', schema);
const answer = User.myStaticMethod(); // 42
實例方法和靜態方法
以下是如何定義同時具有實例方法和靜態方法的模型。
import { Model, Schema, HydratedDocument, model } from 'mongoose';
interface IUser {
firstName: string;
lastName: string;
}
interface IUserMethods {
fullName(): string;
}
interface UserModel extends Model<IUser, {}, IUserMethods> {
createWithFullName(name: string): Promise<HydratedDocument<IUser, IUserMethods>>;
}
const schema = new Schema<IUser, UserModel, IUserMethods>({
firstName: { type: String, required: true },
lastName: { type: String, required: true }
});
schema.static('createWithFullName', function createWithFullName(name: string) {
const [firstName, lastName] = name.split(' ');
return this.create({ firstName, lastName });
});
schema.method('fullName', function fullName(): string {
return this.firstName + ' ' + this.lastName;
});
const User = model<IUser, UserModel>('User', schema);
User.createWithFullName('Jean-Luc Picard').then(doc => {
console.log(doc.firstName); // 'Jean-Luc'
doc.fullName(); // 'Jean-Luc Picard'
});