Background
I'm using mongoose and TypeScript in my Node.JS app. I'm using mongoose's populate in a bunch of places when fetching data from the database.
The issue I'm facing is that I don't know how to type my models so that a property can be either an ObjectId or populated with data from another collection.
What I've tried
I've attempted using union types in my model type definition, which seems like something that TypeScript offers to cover these kind of things:
interface User extends Document {
_id: Types.ObjectId;
name: string
}
interface Item extends Document {
_id: Types.ObjectId;
// Union typing here
user: Types.ObjectId | User;
}
My schema only defines the property as an ObjectId with ref.
const ItemSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User", index: true }
})
Example:
So I might do something like this:
ItemModel.findById(id).populate("user").then((item: Item) => {
console.log(item.user.name);
})
Which produces the compilation error:
[ts] Property 'name' does not exist on type 'User | ObjectId'.
Property 'name' does not exist on type 'ObjectId'.
Question
How can I have a model property that can be either of two types in TypeScript?