Comments (3)
I could do something like this:
export const getParents = async (): Promise<ExpectedParent[]> => {
const parents = await ParentModel.find<ExpectedParent>();
return parents;
};
However, this seems a bit heavy-handed as I am now overriding the entirety of the types stored within the mongoose schemas.
I ended up landing on this utility type:
// Recursive type to enforce `_id` in all subdocuments
type EnforceIdInSubdocuments<T> = {
[K in keyof T]: T[K] extends mongoose.Types.DocumentArray<infer U>
? mongoose.Require_id<U>[]
: T[K] extends object
? EnforceIdInSubdocuments<T[K]>
: T[K];
};
// Utility type to extract and enforce _id in subdocuments
type ModelWithEnforcedIds<T extends mongoose.Model<any>> = EnforceIdInSubdocuments<
mongoose.InferSchemaType<T['schema']>
>;
Full 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<ModelWithEnforcedIds<typeof ParentModel>>();
return parents;
};
interface ExpectedParent {
_id: string;
name: string;
parts: Array<{ _id: string; name: string }>;
}
// Recursive type to enforce `_id` in all subdocuments
type EnforceIdInSubdocuments<T> = {
[K in keyof T]: T[K] extends mongoose.Types.DocumentArray<infer U>
? mongoose.Require_id<U>[]
: T[K] extends object
? EnforceIdInSubdocuments<T[K]>
: T[K];
};
// Utility type to extract and enforce _id in subdocuments
type ModelWithEnforcedIds<T extends mongoose.Model<any>> = EnforceIdInSubdocuments<
mongoose.InferSchemaType<T['schema']>
>;
I will leave this open as I feel like there's probably a better way to do this.
from mongoose.
This looks like expected behavior: you expect your parts
subdocs to have _id: string
, but you don't define an _id
property in ChildSchema
, so Mongoose assumes that parts
subdocs have ObjectId _id
's. To make this script compile correctly, just add an _id
property below:
const ChildSchema = new mongoose.Schema({
_id: { type: String, required: true }, // <-- add _id here
name: { type: String, required: true },
});
Or, if you intend to have ObjectId _id for ChildSchema, do the following:
const ChildSchema = new mongoose.Schema({
_id: { type: 'ObjectId', required: true }, // <-- change _id type here
name: { type: String, required: true },
});
interface ExpectedParent {
_id: string;
name: string;
parts: Array<{ _id: mongoose.Types.ObjectId; name: string }>; // <-- change _id type here
}
Does this help?
from mongoose.
Thanks for the reply @vkarpov15.
This looks like expected behavior: you expect your
parts
subdocs to have_id: string
, but you don't define an_id
property in ChildSchema, so Mongoose assumes thatparts
subdocs have ObjectId_id
's
From my vantage point, the issue is that Mongoose's types do not assume that the parts
subdocs have ObjectId _id
's.
As you are aware, each subdocument has an _id
by default. However, the TS logic does not demonstrate this. I wouldn't classify that as "expected behavior". I do understand that I could change my schema to coerce the type system to acknowledge an _id
property, but that seems more like a work-around. If the Mongoose docs & code are written so that an _id
is to be assumed, I believe the corresponding types should reflect that (hence my view that this is a bug).
from mongoose.
Related Issues (20)
- Embedded documents are missing the `toJSON()` method HOT 1
- Can not creating a Schema with a field named 'parent' HOT 8
- Query recursive model with discriminator not working with string ref id filter HOT 1
- await mongoose.connect() not fully connected HOT 3
- how to search objectid with regex? HOT 3
- địt con bà chúng mày
- Example for findOneAndUpdate is confusing HOT 3
- Unable to use `$pull` on nested array within discriminated union
- Document.prototype.validate() does not validate subdocument required fields with validateModifiedOnly option HOT 1
- BulkWrite updateOne with filter $elemMatch { $elemMatch: { $in: [] } } throwing TypeError HOT 1
- Model.hydrate() should work with subdocument array projection
- Private PKG: MongooseError: Operation `users.findOne()` buffering timed out after 10000ms HOT 3
- DocumentNotFoundError: No document found for query on using delete function HOT 2
- In which case the ID field is automatically converted to ObjectId? HOT 1
- Query.count / Query.findOneAndRemove are still alive
- MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster HOT 9
- mongoose.Types.ObjectId(string) - Expected 0 arguments, but got 1 HOT 4
- InferSchemaType with arrays make all fields undefined HOT 3
- Validate in schema options is not properly typed
- TypeScript does not return an error when assigning the result of a `lean` query to a variable of type `InstanceType<Model<MyModel>>` HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mongoose.