javascript - Mongoose TypeScript ObjectId-typomvandling - Typ 'string' kan inte tilldelas typen 'Condition'
Jag har problem med Mongoose-frågor när jag frågar efter ett ObjectId-fält. Att använda mongoose.Types.ObjectId eller string båda ger fel. TypeScript slutar bara klaga när jag castar ObjectId till mongoose.Schema.Types.ObjectId, vilket sedan kraschar vid körning eftersom det inte är ett giltigt ObjectId.
interface DocumentWithTimestamp extends Document<ObjectId> {
createdAt: Date;
updatedAt: Date;
}
Först och främst märkte jag att Dokumentet definierar _id som ObjectId | undefined, vilket redan komplicerar allt.
Jag definierar mina scheman på följande sätt:
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);
Nu ger en fråga till min LanguageModel med _id eller något annat ObjectId-fält typfel:
export async function findLanguagesByIds(languageIds: string[]) {
return LanguageModel.find({ _id: { $in: languageIds } }).lean();
}
Fel :
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[]>'.
När jag försöker kasta string[] till Schema.Types.ObjectId[]-arrayen försvinner felet, men detta kan inte vara lösningen eftersom det kraschar vid körning (Schema.Types.ObjectId är inte en giltig ObjectId).
const languages = await LanguageModel.find({
_id: { $in: languageIds.map((id) => new mongoose.Schema.Types.ObjectId(id)) },
}).lean();
Om jag kastar till mongoose.Types.ObjectId (till en riktig ObjectId) så kastar det fel igen...
All hjälp uppskattas!
Svar #1
Jag hittade lösningen på mitt problem.
mongoose-dokument definieras på följande sätt:
class Document<T = any, TQueryHelpers = any, DocType = any> {
constructor(doc?: any);
/** This documents _id. */
_id?: T;
// ...
}
Jag utökade det med Document<ObjectId>. ObjectId-typen var dock Schema-typen, till exempel.
import { ObjectId } from "mongoose";
Men det borde faktiskt ha varit den faktiska ObjectId-typen i mongoose och inte Schema-typen!
ÅTGÄRDA :
import { Types } from "mongoose"
interface DocumentWithTimestamp extends Document<Types.ObjectId> {
createdAt: Date;
updatedAt: Date;
}
Svar #2
Jag har en smutsig lösning
I mitt fall behöver jag filtrera efter användar-ID, samma fel.
Denna parse fixar det: som okänd som ObjectId
const userId = req.userId as unknown as ObjectId;
const res: IPostDocument[] = await Post.find({userId: userId})
