Tengo problemas con las consultas de mangosta cuando consulto por un campo ObjectId. Pasar mongoose.Types.ObjectId o string arroja errores. TypeScript solo deja de quejarse cuando lanzo ObjectId a mongoose.Schema.Types.ObjectId , que luego falla en el tiempo de ejecución porque no es un ObjectId válido.
interface DocumentWithTimestamp extends Document<ObjectId> { createdAt: Date; updatedAt: Date; } En primer lugar, noté que Document define _id como ObjectId | undefined , que ya lo complica todo.
Defino mis esquemas de la siguiente manera:
export interface LanguageSchema extends DocumentWithTimestamp { langCode: string; locale: string; } interface LanguageModel extends Model<LanguageSchema> { mapToLanguage(language: LeanDocument<LanguageSchema> | LanguageSchema): Language; } const languageSchema = new Schema<LanguageSchema, LanguageModel>( { langCode: { type: String, required: true, trim: true }, locale: { type: String, unique: true, required: true, trim: true }, }, { collection: 'language', timestamps: true, versionKey: false }, ); languageSchema.statics.mapToLanguage = function (language: LeanDocument<LanguageSchema> | LanguageSchema): Language { return { id: language._id?.toString() || '', // why is _id conditional...? langCode: language.langCode, locale: language.locale, }; }; export const LanguageModel = model<LanguageSchema, LanguageModel>('Language', languageSchema);Ahora consultar mi LanguageModel por _id o cualquier otro campo de ObjectId arroja errores de tipo:
export async function findLanguagesByIds(languageIds: string[]) { return LanguageModel.find({ _id: { $in: languageIds } }).lean(); }Error:
Argument of type '{ _id: { $in: string[]; }; }' is not assignable to parameter of type 'Callback<LanguageSchema[]>'. Object literal may only specify known properties, and '_id' does not exist in type 'Callback<LanguageSchema[]>'.Cuando trato de convertir string[] a la matriz Schema.Types.ObjectId[], el error desaparece, pero esta no puede ser la solución, ya que falla en el tiempo de ejecución (Schema.Types.ObjectId no es un ObjectId válido).
const languages = await LanguageModel.find({ _id: { $in: languageIds.map((id) => new mongoose.Schema.Types.ObjectId(id)) }, }).lean(); Si lanzo a mongoose.Types.ObjectId (a un ObjectId real), arroja errores nuevamente ...
¡Cualquier ayuda es apreciada!
Encontré la solución a mi problema.
El documento mangosta se define de la siguiente manera:
class Document<T = any, TQueryHelpers = any, DocType = any> { constructor(doc?: any); /** This documents _id. */ _id?: T; // ... } Lo extendí usando Document<ObjectId> . Sin embargo, el tipo ObjectId era el tipo Schema, por ejemplo
import { ObjectId } from "mongoose";¡Pero en realidad debería haber sido el tipo ObjectId real de mangosta y no el tipo Schema!
ARREGLAR:
import { Types } from "mongoose" interface DocumentWithTimestamp extends Document<Types.ObjectId> { createdAt: Date; updatedAt: Date; }