Skip to content
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

Breaking types of toObject on SubDocument or ArraySubdocument #14601

Closed
2 tasks done
piyushk96 opened this issue May 17, 2024 · 1 comment · Fixed by #14612
Closed
2 tasks done

Breaking types of toObject on SubDocument or ArraySubdocument #14601

piyushk96 opened this issue May 17, 2024 · 1 comment · Fixed by #14612
Milestone

Comments

@piyushk96
Copy link

piyushk96 commented May 17, 2024

Prerequisites

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

Mongoose version

8.3.4

Node.js version

20

MongoDB server version

6.6

Typescript version (if applicable)

5.4.5

Description

Since Mongoose v7, the type of the results obtained by calling toObject on SubDocument or ArraySubdocument is any. Prior to v7 toObject return type was working fine.

Steps to Reproduce

** Code for version >=v7 **

import mongoose, { Types, model } from 'mongoose';
const { Schema } = mongoose;

mongoose.connect('mongodb://localhost:27017/testdb');

interface ISub {
  field1: string;
}
interface IMain {
  f1: string;
  f2: ISub & Types.Subdocument;
  f3: (ISub & Types.ArraySubdocument)[];
}

const subSchema = new Schema({ field1: String }, { _id: false });

const mainSchema = new Schema({
  f1: String,
  f2: { type: subSchema },
  f3: { type: [subSchema] }
})
const MainModel = model<IMain>("Main", mainSchema);

const item = new MainModel({
  f1: "test",
  f2: { field1: "test" },
  f3: [{ field1: "test" }]
})

const obj = item.toObject();

const obj2 = item.f2.toObject()
image image

** Code for version < v7 **

import mongoose, { Types, model, Document } from 'mongoose';
const { Schema } = mongoose;

mongoose.connect('mongodb://localhost:27017/testdb');

interface ISub {
  field1: string;
}
interface IMain {
  f1: string;
  f2: ISub & Types.Subdocument;
  f3: (ISub & Types.ArraySubdocument)[];
}

type IMainDoc = IMain & Document;

const subSchema = new Schema({ field1: String }, { _id: false });

const mainSchema = new Schema({
  f1: String,
  f2: { type: subSchema },
  f3: { type: [subSchema] }
})
const MainModel = model<IMainDoc>("Main", mainSchema);

const item = new MainModel({
  f1: "test",
  f2: { field1: "test" },
  f3: [{ field1: "test" }]
})

const obj = item.toObject();

const obj2 = item.f2.toObject()
const obj3 = item.f3[0].toObject()
image image

Expected Behavior

Both obj2 and obj3 should have proper types

@vkarpov15
Copy link
Collaborator

In Mongoose 7, we recommend using HydratedSingleSubdocument and HydratedArraySubdocument rather than ISub & Types.Subdocument. With #14612, the following will no longer return any

  interface IMain {
    f1: string;
    f2: HydratedSingleSubdocument<ISub>;
    f3: HydratedArraySubdocument<ISub>[];
  }

@vkarpov15 vkarpov15 added this to the 7.6.13 milestone May 24, 2024
vkarpov15 added a commit that referenced this issue May 30, 2024
types: pass DocType down to subdocuments so `HydratedSingleSubdocument` and `HydratedArraySubdocument` `toObject()` returns correct type
@vkarpov15 vkarpov15 reopened this May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants