Skip to content

string cannot be used for PopulatedDoc<T, ObjectId> (regression) #16316

Description

@hasezoey

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

since 9.3.0 (tested in 9.6.0)

Node.js version

any

MongoDB server version

unrelated

Typescript version (if applicable)

5.9.3

Description

Since 9.3.0 (bisect says since 3971dc7) using mongoose.PopulatedDoc with ObjectId as the RefType (default), it is not possible to assign string to it, resulting in:

src/test.ts:30:43 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'string' is not assignable to type 'ObjectId | { dummy?: string | undefined; } | { [x: string]: unknown; readonly _bsontype?: RegExp | "ObjectId" | undefined; id?: { [x: number]: number | undefined; readonly BYTES_PER_ELEMENT?: number | undefined; ... 37 more ...; readonly [Symbol.toStringTag]?: "Uint8Array" | undefined; } | { ...; } | undefined; ... ...'.

30   const other = await otherModel.create({ to: userId });
                                             ~~

  src/test.ts:12:3
    12   to: mongoose.PopulatedDoc<User>;
         ~~
    The expected type comes from property 'to' which is declared here on type '{ to?: ObjectId | { dummy?: string | undefined; } | { [x: string]: unknown; readonly _bsontype?: RegExp | "ObjectId" | undefined; id?: { [x: number]: number | undefined; readonly BYTES_PER_ELEMENT?: number | undefined; ... 37 more ...; readonly [Symbol.toStringTag]?: "Uint8Array" | undefined; } | { ...; } | undefine...'
  node_modules/mongoose/types/models.d.ts:315:5
    315     create(...docs: Array<DeepPartial<ApplyBasicCreateCasting<Require_id<TRawDocType>>>>): Promise<THydratedDocumentType[]>;
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The last overload is declared here.


Found 1 error in src/test.ts:30

Note that this does not happen if the type is changed to just mongoose.Types.ObjectId or when using schema inference.

Steps to Reproduce

// NodeJS: 25.2.1
// MongoDB: 7.0 (Docker)
// Typescript 5.9.3
import * as mongoose from 'mongoose'; // mongoose@9.6.0

interface User {
  dummy: string;
}

interface Other {
  to: mongoose.PopulatedDoc<User>;
}

const userSchema = new mongoose.Schema({ dummy: String });
const userModel = mongoose.model<User>('user', userSchema);

const otherSchema = new mongoose.Schema({ to: { type: mongoose.Types.ObjectId, ref: 'user' } });
const otherModel = mongoose.model<Other>('other', otherSchema);

async function main() {
  await mongoose.connect(`mongodb://localhost:27017/`, {
    dbName: 'verifyMASTER',
  });

  const user = await userModel.create({ dummy: 'hello' });

  const userId = user._id.toString();

  // type error: "Type 'string' is not assignable to ..."
  const other = await otherModel.create({ to: userId });

  console.log('Done', other);

  await mongoose.disconnect();
}

main();

Reproduction repository & branch

Expected Behavior

To also allow string as a possibility when ObjectId is used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    typescriptTypes or Types-test related issue / Pull Request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions