背景
我在我的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中的两种类型之一?
5条答案
按热度按时间ztigrdn81#
您需要使用类型保护来将类型从
Types.ObjectId | User
缩小到User
...如果你正在处理一个
User
类,你可以使用:如果你有一个与
User
匹配的结构,但它不是一个类的示例(例如,如果User
是一个接口),你需要一个自定义类型保护:您可以将其用于:
如果不想为此检查结构,可以使用discriminated union。
oiopk7p52#
填充用户时,将
item.user
强制转换为User
。v440hwme3#
您可以使用
@types/mongoose
库中的PopulatedDoc
类型。请参见mongoose.doc。q9rjltbz4#
Mongoose的TypeScript绑定导出一个PopulatedDoc类型,帮助您在TypeScript定义中定义填充的文档:
下面是PopulatedDoc类型的简化实现,它有两个通用参数:已填充的文档类型PopulatedType和未填充的类型RawId。RawId默认为ObjectId。
作为开发人员,您有责任在填充和未填充的文档之间强制执行强类型。
这是从文档中提取的。您可以检查它here
cig3rfwq5#
抱歉迟到了,这里是要使用 typescript 填充的official way。
或