gpt4 book ai didi

node.js - TypeScript - 如何结合使用 Mongoose 填充来定义模型?

转载 作者:IT老高 更新时间:2023-10-28 23:21:35 30 4
gpt4 key购买 nike

背景

我在我的 Node.JS 应用程序中使用 Mongoose 和 TypeScript。从数据库中获取数据时,我在很多地方都使用了 Mongoose 的 populate

我面临的问题是我不知道如何键入我的模型,以便属性可以是 ObjectId 或填充来自另一个集合的数据。

我尝试过的

我尝试在我的模型类型定义中使用联合类型,这似乎是 TypeScript 提供的用于涵盖这些类型的东西:

interface User extends Document {
_id: Types.ObjectId;
name: string
}

interface Item extends Document {
_id: Types.ObjectId;

// Union typing here
user: Types.ObjectId | User;
}

我的架构仅将属性定义为带有 ref 的 ObjectId。

const ItemSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User", index: true }
})

示例:

所以我可能会这样做:

ItemModel.findById(id).populate("user").then((item: Item) => {
console.log(item.user.name);
})

产生编译错误:

[ts] Property 'name' does not exist on type 'User | ObjectId'.
Property 'name' does not exist on type 'ObjectId'.

问题

如何在 TypeScript 中拥有可以是两种类型之一的模型属性?

最佳答案

您需要使用类型保护来缩小 Types.ObjectId | 中的类型。用户用户...

如果你正在处理一个 User 类,你可以使用这个:

if (item.user instanceof User) {
console.log(item.user.name);
} else {
// Otherwise, it is a Types.ObjectId
}

如果您的结构与 User 匹配,但不是类的实例(例如,如果 User 是一个接口(interface)),您将需要一个自定义类型保护:

function isUser(obj: User | any) : obj is User {
return (obj && obj.name && typeof obj.name === 'string');
}

你可以使用的:

if (isUser(item.user)) {
console.log(item.user.name);
} else {
// Otherwise, it is a Types.ObjectId
}

如果您不想为此检查结构,可以使用 discriminated union .

关于node.js - TypeScript - 如何结合使用 Mongoose 填充来定义模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47923403/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com