Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js TypeScript-如何结合使用mongoose填充定义模型? 背景_Node.js_Typescript_Mongoose - Fatal编程技术网

Node.js TypeScript-如何结合使用mongoose填充定义模型? 背景

Node.js TypeScript-如何结合使用mongoose填充定义模型? 背景,node.js,typescript,mongoose,Node.js,Typescript,Mongoose,我在Node.JS应用程序中使用mongoose和TypeScript。在从数据库获取数据时,我在很多地方使用mongoose的填充 我面临的问题是,我不知道如何键入模型,以便属性可以是ObjectId,也可以使用其他集合中的数据填充 我试过的 我尝试在我的模型类型定义中使用联合类型,这似乎是TypeScript提供的涵盖这类内容的东西: interface User extends Document { _id: Types.ObjectId; name: string }

我在Node.JS应用程序中使用mongoose和TypeScript。在从数据库获取数据时,我在很多地方使用mongoose的
填充

我面临的问题是,我不知道如何键入模型,以便属性可以是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
缩小到
User

如果您处理的是
用户
类,则可以使用以下方法:

if (item.user instanceof User) {
    console.log(item.user.name);
} else {
    // Otherwise, it is a Types.ObjectId
}
如果您的结构与
用户
匹配,但不是类的实例(例如,如果
用户
是接口),则需要自定义类型的保护:

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
}

如果不想为此检查结构,则可以在填充用户时使用。

项.user
强制转换为
user

ItemModel.findById(id).填充(“用户”)。然后((项:项)=>{
console.log((item.user.name);
})

我确实读过关于类型保护的内容,并尝试应用它们,但我的tsc输出错误。它说,
[ts]“User”只指一个类型,但在这里用作值。
对于行
如果(item.User instanceof User){…}
@maxpaj
instanceof
需要一个具体的类型-它不会与接口一起工作。第二个选项是自定义类型保护,这对我来说非常有效,并给了我阅读一般类型保护的线索。谢谢对不起,它坏了。正如maxpaj所说,您有一个错误“User”只引用一个类型。。。。使用typeof obj==='Interface',它将始终返回false