title: TypeScript - How to define model in combination with using mongoose populate?
body: <h2>Background</h2>
  
  <p>I'm using mongoose and TypeScript in my Node.JS app. I'm using mongoose's <code>populate</code> in a bunch of places when fetching data from the database. </p>
  
  <p>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. </p>
  
  <h2>What I've tried</h2>
  
  <p>I've attempted using union types in my model type definition, which seems like something that TypeScript offers to cover these kind of things:</p>
  
  <pre><code>interface User extends Document {
      _id: Types.ObjectId;
      name: string
  }
  
  interface Item extends Document {
      _id: Types.ObjectId;
  
      // Union typing here
      user: Types.ObjectId | User;
  }
  </code></pre>
  
  <p>My schema only defines the property as an ObjectId with ref. </p>
  
  <pre><code>const ItemSchema = new Schema({
      user: { type: Schema.Types.ObjectId, ref: "User", index: true }
  })
  </code></pre>
  
  <p><strong>Example</strong>:</p>
  
  <p>So I might do something like this: </p>
  
  <pre><code>ItemModel.findById(id).populate("user").then((item: Item) =&gt; {
      console.log(item.user.name);
  })
  </code></pre>
  
  <p>Which produces the compilation error: </p>
  
  <pre><code>[ts] Property 'name' does not exist on type 'User | ObjectId'.
       Property 'name' does not exist on type 'ObjectId'.
  </code></pre>
  
  <h2>Question</h2>
  
  <p>How can I have a model property that can be either of two types in TypeScript?</p>