Skip to content

BREAKING CHANGE: consolidate RootQuerySelector, Condition, etc. types with MongoDB driver's #15593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 9.0
Choose a base branch
from

Conversation

vkarpov15
Copy link
Collaborator

Summary

QuerySelector, RootQuerySelector, and Condition are almost exactly duplicates of types the MongoDB Node driver exports. With a little work, we can make it so that Mongoose uses the MongoDB driver's types rather than maintaining its own (which may be out of date).

Examples

@vkarpov15 vkarpov15 added this to the 9.0 milestone Aug 18, 2025
@vkarpov15 vkarpov15 added backwards-breaking typescript Types or Types-test related issue / Pull Request labels Aug 18, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR consolidates type definitions by replacing Mongoose's internal type definitions with the MongoDB driver's equivalent types, eliminating duplicate type maintenance. This is a breaking change that standardizes on MongoDB driver types for better consistency and reduced maintenance overhead.

  • Removes imports of Condition and QuerySelector from Mongoose
  • Updates usage to import and use mongodb.Condition instead
  • Simplifies type annotations in test files

Reviewed Changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/types/queries.test.ts Replaces Mongoose's Condition and QuerySelector with MongoDB driver equivalents
test/types/populate.test.ts Updates type annotations to use more appropriate generic types

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

const child = doc.child;
if (child == null || child instanceof ObjectId) {
throw new Error('should be populated');
} else {
useChildDoc(child);
}
const lean = doc.toObject<typeof doc>();
const lean = doc.toObject<mongoose.MergeType<Parent, { Child: Child }>>();
Copy link
Preview

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type parameter has inconsistent casing. The property should be child (lowercase) to match the schema field name, not Child (uppercase).

Suggested change
const lean = doc.toObject<mongoose.MergeType<Parent, { Child: Child }>>();
const lean = doc.toObject<mongoose.MergeType<Parent, { child: Child }>>();

Copilot uses AI. Check for mistakes.

Copy link
Collaborator

@hasezoey hasezoey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the surface this looks like a good change, but in its current state it causes some errors like the 2 below in typegoose:

src/typeguards.ts:21:12 - error TS2677: A type predicate's type must be assignable to its parameter's type.
  Type 'Array<DocumentType<NonNullable<T>>>' is not assignable to type 'Array<Ref<T, S>>'.
    Type 'DocumentType<NonNullable<T>>' is not assignable to type 'Ref<T, S>'.
      Type 'DocumentType<NonNullable<T>>' is not assignable to type 'DocumentType<T, BeAnObject>'.
        Type 'DocumentType<NonNullable<T>>' is not assignable to type 'Document<unknown, BeAnObject, T, DefaultIdVirtual, {}>'.

21 ): docs is mongoose.Types.Array<DocumentType<NonNullable<T>>>;

(this one at least can be solved by removing the NonNullable<>, though i dont know why it wouldnt be compatible)

test/tests/ref.test.ts:93:3 - error TS2322: Type 'Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<{ _id: string; }> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction' is not assignable to type 'Ref<RefTestStringOptional> | undefined'.
  Type 'Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<{ _id: string; }> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction' is not assignable to type 'DocumentType<RefTestStringOptional, BeAnObject>'.
    Type 'Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<{ _id: string; }> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction' is not assignable to type 'Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>'.
      The types returned by 'deleteOne(...)' are incompatible between these types.
        Type 'QueryWithHelpers<DeleteResult, Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<...> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction, BeAnObject, RefTestString, "deleteOne", Record<...>>' is not assignable to type 'QueryWithHelpers<DeleteResult, Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>, BeAnObject, RefTestStringOptional, "deleteOne", Record<...>>'.
          Type 'QueryWithHelpers<DeleteResult, Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<...> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction, BeAnObject, RefTestString, "deleteOne", Record<...>>' is not assignable to type 'Query<DeleteResult, Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>, BeAnObject, RefTestStringOptional, "deleteOne", Record<...>>'.
            The types returned by '$where(...)' are incompatible between these types.
              Type 'QueryWithHelpers<(Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<{ _id: string; }> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction)[], ... 4 more ..., Record<...>>' is not assignable to type 'QueryWithHelpers<Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>[], Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>, BeAnObject, RefTestStringOptional, "deleteOne", Record<...>>'.
                Type 'QueryWithHelpers<(Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<RefTestString & Required<{ _id: string; }> & { ...; }, "id" | "typegooseName"> & DefaultIdVirtual & IObjectWithTypegooseFunction)[], ... 4 more ..., Record<...>>' is not assignable to type 'Query<Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>[], Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>, BeAnObject, RefTestStringOptional, "deleteOne", Record<...>>'.
                  Types of property 'and' are incompatible.
                    Type '(array: FilterQuery<RefTestString>[]) => QueryWithHelpers<(Document<unknown, BeAnObject, RefTestString, DefaultIdVirtual, {}> & Omit<...> & DefaultIdVirtual & IObjectWithTypegooseFunction)[], ... 4 more ..., Record<...>>' is not assignable to type '(array: FilterQuery<RefTestStringOptional>[]) => Query<Document<unknown, BeAnObject, RefTestStringOptional, DefaultIdVirtual, {}>[], ... 4 more ..., Record<...>>'.
                      Types of parameters 'array' and 'array' are incompatible.
                        Type 'FilterQuery<RefTestStringOptional>[]' is not assignable to type 'FilterQuery<RefTestString>[]'.
                          Type 'FilterQuery<RefTestStringOptional>' is not assignable to type 'FilterQuery<RefTestString>'.
                            Type '{ _id?: Condition<ApplyBasicQueryCasting<StringQueryTypeCasting | undefined>>; } & RootFilterOperators<{ _id?: ApplyBasicQueryCasting<StringQueryTypeCasting | undefined>; }>' is not assignable to type 'FilterQuery<RefTestString>'.
                              Type '{ _id?: Condition<ApplyBasicQueryCasting<StringQueryTypeCasting | undefined>>; } & RootFilterOperators<{ _id?: ApplyBasicQueryCasting<StringQueryTypeCasting | undefined>; }>' is missing the following properties from type 'Query<any, any, {}, unknown, "find", Record<string, never>>': _mongooseOptions, exec, all, allowDiskUse, and 93 more.

93   refTypeTest.refFieldStringOptional = new RefTestStringModel();
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note that this error seemingly only happens to classes which have _id?: Type (or _id: Type | undefined). (which is i think used to make it optional for defaulting)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backwards-breaking typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants