Mongoose TypeScript ObjectId 转换 - 类型“string”不可分配给类型“Condition<ObjectId | undefined>”

问题描述 投票:0回答:3

当我通过 ObjectId 字段查询时,我遇到猫鼬查询问题。传递

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),它会再次抛出错误......

如有任何帮助,我们将不胜感激!

javascript node.js typescript mongodb mongoose
3个回答
9
投票

我找到了解决问题的方法。

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";

但它实际上应该是 mongoose 的实际 ObjectId 类型,而不是 Schema 类型!

修复:

import { Types } from "mongoose"

interface DocumentWithTimestamp extends Document<Types.ObjectId> {
  createdAt: Date;
  updatedAt: Date;
}

2
投票

我有一个肮脏的解决方案

就我而言,我需要按用户 ID 进行过滤,同样的错误。

此解析修复了它:与 ObjectId 一样未知

const userId = req.userId as unknown as ObjectId;

const res: IPostDocument[] = await Post.find({userId: userId})

0
投票

你也可以尝试这样做 --> { _id: 新的 ObjectId(id) }

并且您可以从 MongoDB 导入 ObjectId --> 从“MongoDB”导入{ObjectId};

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.