-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Closed
Labels
helpThis issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessaryThis issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessaryhelp wanted
Milestone
Description
Prerequisites
- I have written a descriptive issue title
Mongoose version
8.2.3
Node.js version
20.14.0
MongoDB version
?
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
14.1
Issue
I have a Mongoose model which has a subdocument. I have a function that queries the model via the .find()
method. The function's output is expected to conform to an output interface, however it is not playing nicely with the the auto-generated TypeScript types for the model. The mongoose docs state: "Each subdocument has an _id
by default", however the types for the DocumentArray
properties returned from a find()
operation do not have _id
marked as required.
This feels like a bug on the Mongoose side but I am new to using the library so it's possible that I'm missing something.
Questions:
- Am I correct that it is safe to assume that any subdocuments will have an
_id
property when a document is retrieved via the.find()
operations? (safe for any situations where I explicitly instruct Mongoose to not place an_id
on the subdocument, of course) - Short of a change in
mongoose
code itself, how can I customize the output of the types in a succinct manner? I'd prefer to not write my own types for the Schema and Model as mongoose does a good job inferring these values and I would like to avoid maintaining redundant code. I see that.find()
is a generic function (link), so I could provide my own type that instructsmongoose
that the_id
is required, however I'm struggling to achieve that.
Simplified example:
import mongoose from 'mongoose';
const ChildSchema = new mongoose.Schema({
name: { type: String, required: true },
});
const ParentSchema = new mongoose.Schema({
_id: { type: String, required: true },
name: { type: String, required: true },
parts: { type: [ChildSchema] },
});
const ParentModel = mongoose.model('Parent', ParentSchema);
export const getParents = async (): Promise<ExpectedParent[]> => {
const parents = await ParentModel.find();
return parents; // TypeScript error here!
};
interface ExpectedParent {
_id: string;
name: string;
parts: Array<{ _id: string; name: string }>;
}
I see the following error from TS:
Type '(Document<unknown, {}, { name: string; _id: string; parts: DocumentArray<{ name: string; }>; }> & { name: string; _id: string; parts: DocumentArray<{ name: string; }>; } & Required<...>)[]' is not assignable to type 'ExpectedParent[]'.
Type 'Document<unknown, {}, { name: string; _id: string; parts: DocumentArray<{ name: string; }>; }> & { name: string; _id: string; parts: DocumentArray<{ name: string; }>; } & Required<...>' is not assignable to type 'ExpectedParent'.
The types returned by 'parts.pop()' are incompatible between these types.
Type '(Subdocument<ObjectId> & { name: string; }) | undefined' is not assignable to type '{ _id: string; name: string; } | undefined'.
Type 'Subdocument<ObjectId> & { name: string; }' is not assignable to type '{ _id: string; name: string; } | undefined'.
Type 'Subdocument<ObjectId> & { name: string; }' is not assignable to type '{ _id: string; name: string; }'.
Types of property '_id' are incompatible.
Type 'ObjectId | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
Metadata
Metadata
Assignees
Labels
helpThis issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessaryThis issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessaryhelp wanted