mongoose
mongoose copied to clipboard
Intersection type error in embedded schema when iterating through an embedded array
Prerequisites
- [X] I have written a descriptive issue title
- [X] I have searched existing issues to ensure the bug has not already been reported
Mongoose version
8.5.2
Node.js version
20.10.0
MongoDB server version
6.0.2
Typescript version (if applicable)
5.5.4
Description
I have a complex Mongoose schema: my model has an embedded field which in turn has an array of embedded fields. This last field contains a virtual field.
interface IPost {
detail: IDetail;
}
interface IDetail {
comments: IComment[];
}
interface IComment {
// ...
}
In the embedded detail, I declare comments in IDetail
as IComment[]
, and in the type DetailDocumentOverrides
, I declare comments as CommentInstance[]
. CommentInstance is of type: Types.Subdocument<Types.ObjectId> & IComment & ICommentVirtuals
.
There is a difference in typing when I access a comment directly or when I iterate over them, for example: post.detail.comments[0]
is of type CommentInstance
, so I can access the virtual field; however, if I iterate: post.detail.comments.forEach((comment) => { … })
, the variable comment is of type IComment
, but this is not entirely correct, because comment actually contains all the other properties hydrated by Mongoose.
The actual type generated for the comments field is IComment[] & CommentInstance[]
, but it’s not a good idea to generate types this way, as suggested by an active member of the TypeScript team (stackoverflow comment, github issue).
Am I wrong in typing the embedded fields? In this case, feel free to correct my code.
In the following screen, TypeScript does not return an error in the first line, while it does inside the forEach (“user” is a virtual field):
A workaround is to type the comment variable inside the forEach as CommentInstance. However, I wanted to understand if this is a problem that can be solved in some way, if I will always have to type manually in these cases, or if I am wrong in typing the embedded fields.
Steps to Reproduce
Reproduction link: stackblitz
Expected Behavior
No response