英文:
Interface for populated docs mongoose 7.3.x
问题
让我们假设我有以下模型 User
:
import { Schema, model, Types, HydratedDocument } from "mongoose";
interface IUser {
_id: Types.ObjectId;
name: string;
parent: Types.ObjectId;
}
interface IUserPopulate {
parent: IUser;
}
type MergePopulate<I, IP> = Omit<HydratedDocument<I>, keyof IP> & IP;
const UserSchema = new Schema<IUser>({
name: String,
parent: { type: Schema.Types.ObjectId, ref: "users" },
});
const UserModel = model("users", UserSchema);
然后,我使用 UserModel#find
方法来查找用户:
async function getUser() {
const users = await UserModel.find().populate<IUserPopulate>("parent");
users.forEach((user) => {
processUser(user);
});
}
并且 processUser
函数接受已经填充的用户文档:
async function processUser(user: MergePopulate<IUser, IUserPopulate>) {
// 做一些事情
}
TypeScript 可以接受使用 find()
方法查找的用户文档,但如果我使用 findOne
或 findById
,TypeScript 就无法接受。
const user = await UserModel.findOne().populate<IUserPopulate>("parent");
processUser(user); // 这里会引发很多错误
我如何为这两种查询定义接口?
请注意,这在 mongoose 版本低于 7 时是有效的,但当我升级到 7.3.0 版本时出现了这个错误。
中文翻译结束,以下是代码部分,无需翻译。
英文:
Let's say I have model User
like bellow
import { Schema, model, Types, HydratedDocument } from "mongoose";
interface IUser {
_id: Types.ObjectId;
name: string;
parent: Types.ObjectId;
}
interface IUserPopulate {
parent: IUser;
}
type MergePopulate<I, IP> = Omit<HydratedDocument<I>, keyof IP> & IP;
const UserSchema = new Schema<IUser>({
name: String,
parent: { type: Schema.Types.ObjectId, ref: "users" },
});
const UserModel = model("users", UserSchema);
then I find users by the method UserModel#find
async function getUser() {
const users = await UserModel.find().populate<IUserPopulate>("parent");
users.forEach((user) => {
processUser(user);
});
}
and function process user accepts populated user's docs
async function processUser(user: MergePopulate<IUser, IUserPopulate>) {
//do some thing
}
Typescript accept user docs when I use find()
but don't accept if I use findOne
or findById
const user = await UserModel.findOne().populate<IUserPopulate>("parent");
processUser(user); //throw alot of error here
How can I define Interface for both query?
Note It's work for mongoose < 7, I just got this error when upgrade mongoose to 7.3.0
答案1
得分: 1
findOne
和 findById
返回一个文档或 null
,因此您必须添加一个测试来排除它们返回 null
的情况:
const user = await UserModel.findOne().populate<IUserPopulate>("parent");
if (user) {
processUser(user);
}
英文:
findOne
and findById
return a document or null
, so you must add a test to eliminate the case where they return null
:
const user = await UserModel.findOne().populate<IUserPopulate>("parent");
if(user) {
processUser(user);
}
答案2
得分: 0
找到了
```typescript
type MergePopulate<I, IP> = Omit<Document<unknown, {}, I & {
_id: Types.ObjectId
}> & Omit<I & {
_id: Types.ObjectId
} & Required<{
_id: Types.ObjectId
}>>, keyof IP> & IP
然后我可以使用合并填充文档的接口
<details>
<summary>英文:</summary>
Found it
```typescript
type MergePopulate<I, IP> = Omit<Document<unknown, {}, I & {
_id: Types.ObjectId
}> & Omit<I & {
_id: Types.ObjectId
} & Required<{
_id: Types.ObjectId
}>, never>, keyof IP> & IP
And then I can use interface of merge populate for populated docs
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论