node.js - Aplicar una clase de TypeScript a un miembro de un documento de Mongoose
Tengo un esquema de mongoose en typescript y ya estoy utilizando una interfaz para las propiedades del propio documento. Quiero crear una clase para que cuando encuentre un documento pueda llamar métodos inmediatamente. También quiero que el documento contenga miembros que sean instancias de otras clases y poder llamar los métodos de esos miembros. ¿Es esto posible? Esto es lo que tengo hasta ahora:
models/user.ts:
import mongoose from '../lib/mongoose';
const Schema = mongoose.Schema;
interface IUser extends mongoose.Document {
username: string;
email: string;
hash: string;
};
var userSchema = new Schema({
username: String,
email: String,
hash: String
});
export default mongoose.model<IUser>('User', userSchema);
En realidad no necesito hacer esto para mi modelo de usuario, pero es el más corto, así que pensé que sería un buen ejemplo. Digamos que quisiera un método para verificar si el correo electrónico del usuario contiene su nombre de usuario.
Aquí hay una clase de usuario simple:
class User {
constructor(public username: string, public email: string, public hash: string) {
}
emailUsernameCheck(): boolean {
return this.email.includes(this.username);
}
}
Quiero poder hacer una llamada como esta:
import User from '../models/user';
User.findOne({username: 'foo'}).emailUsernameCheck();
Digamos también que quiero darle a cada usuario un cuadrado con una altura y un ancho, y que la clase cuadrado tiene un método de área.
Aquí hay una clase de cuadrado de ejemplo:
class square {
constructor(public height: number, public width: number) {
}
area(): number {
return this.height * this.width;
}
}
También quiero poder hacer una llamada así:
import User from '../models/user';
User.findOne({username: 'foo'}).square.area();
Sé que puedo hacer las clases por separado, darles constructores que reciban objetos y construir las clases de esa manera. Haré esto si es la única manera, pero significa importar la clase por separado y agrega un paso extra a cada consulta de base de datos. También abre espacio para errores, ya que las clases se mantienen por separado del esquema. Me encantaría manejar todo esto en mi modelo. ¿Hay algo que pueda agregar a models/user.ts para poder hacer cosas como los ejemplos anteriores?
Respuesta #1
Creo que no es posible usar una clase separada en mongoose.
- Puedes extender el esquema del Modelo de Documento usando métodos de instancia y estáticos
- O define un Tipo de Esquema Personalizado para tus campos usando clases separadas (puedes encontrar un ejemplo completo en Mongoose tipo de objeto de esquema personalizado avanzado).
Por cierto, puedes copiar métodos de un objeto externo y del prototipo a Schema.* y Schema.methods.*, pero el objeto final no compartirá el mismo prototipo que la clase de origen (instanceof).