Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>'
Posted
技术标签:
【中文标题】Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>\'【英文标题】:Mongoose TypeScript ObjectId casting - Type 'string' is not assignable to type 'Condition<ObjectId | undefined>'Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>' 【发布时间】:2021-11-23 11:10:58 【问题描述】:当我通过 ObjectId 字段进行查询时,我遇到了 mongoose 查询问题。传递mongoose.Types.ObjectId
或string
都会引发错误。只有当我将 ObjectId 转换为 mongoose.Schema.Types.ObjectId
时,TypeScript 才会停止抱怨,然后它会在运行时崩溃,因为它不是有效的 ObjectId。
interface DocumentWithTimestamp extends Document<ObjectId>
createdAt: Date;
updatedAt: Date;
首先,我注意到 Document 将 _id
定义为 ObjectId | undefined
,这已经使一切复杂化了。
我将我的模式定义如下:
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);
现在通过 _id 或任何其他 ObjectId 字段查询我的 LanguageModel 会引发类型错误:
export async function findLanguagesByIds(languageIds: string[])
return LanguageModel.find( _id: $in: languageIds ).lean();
错误:
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[]>'.
当我尝试将 string[] 转换为 Schema.Types.ObjectId[] 数组时,错误消失了,但这不是解决方案,因为它在运行时崩溃(Schema.Types.ObjectId 不是有效的 ObjectId)。
const languages = await LanguageModel.find(
_id: $in: languageIds.map((id) => new mongoose.Schema.Types.ObjectId(id)) ,
).lean();
如果我转换为 mongoose.Types.ObjectId
(转换为真正的 ObjectId),它会再次引发错误...
感谢任何帮助!
【问题讨论】:
【参考方案1】:我找到了解决问题的方法。
mongoose 文件定义如下:
class Document<T = any, TQueryHelpers = any, DocType = any>
constructor(doc?: any);
/** This documents _id. */
_id?: T;
// ...
我使用Document<ObjectId>
对其进行了扩展。然而,ObjectId 类型是 Schema 类型,例如
import ObjectId from "mongoose";
但它实际上应该是猫鼬的实际 ObjectId 类型而不是 Schema 类型!
修复:
import Types from "mongoose"
interface DocumentWithTimestamp extends Document<Types.ObjectId>
createdAt: Date;
updatedAt: Date;
【讨论】:
这里来自 mongoose 的超级令人困惑的 api.... 他们需要更好的支持。甚至不知道为什么你必须定义一个模型和一个接口......巨大的痛苦以上是关于Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>'的主要内容,如果未能解决你的问题,请参考以下文章
typescript 使用TypeScript和MongoDb的Mongoose示例
typescript 使用TypeScript和MongoDb的Mongoose示例
typescript 使用TypeScript和MongoDb的Mongoose示例
Mongoose 的 loadClass() 和 TypeScript