-
Notifications
You must be signed in to change notification settings - Fork 26
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
Moving from plain array to mongoose.Types.DocumentArray #108
Comments
Sorry for the delay @Dezzymei, yes arrays can be tricky here with Typescript. I find the best thing to do is always use Eg
I don't have a computer to test this right now, so let me know if you still have issues and I'll get back to you ASAP. |
Mongoose arrays get initiated with an empty array by default, so you don't even need to initialize it to an empty array. |
Not quite convinced this does work though. It kind of removes the type checking that I wanted to get as the following does not throw an error:
The rest of this might be moot then: Also, how can I make the array empty? i.e. I would have done:
I also have an array of strings in here but I have no idea how to create it from scratch without using something like this:
(I do realise this is probably more of a question for mongoose than yourself!) Thanks for your help! |
Hmm yeah I see your point. You could use the generated array type to ensure type safety, and then push into the Mongoose array like so:
for setting to an empty array, you may have to do some type casting, or just |
I don't really like that solution, but I am guessing this is perhaps more of a If you do have a solution I would love to implement it because right now it doesn't feel very typesafe for these properties... |
Yes unfortunately this is something I haven't been able to get around with Mongoose. I would look into the Mongoose docs for Typescript usage, its possible that things have changed since I last dove into it. In terms of type safety, I think the solution above is decently safe; you are still using |
I raised a stackoverflow to see if the world can help me! :) |
Hey, great library! @francescov1 Any update on this issue? @Dezzymei |
I have the following model:
Which generates:
When I try and set the value of opening hours:
I receive a similar error:
|
hey @maxshugar let me revisit this in the next few days, i'll see if there's been any updates to Mongoose typing to provide a better solution here. |
Looks like the way Mongoose does it natively is to set subdocument types on schemas to a regular object, rather than the true Subdocument type. Then they ask users to explicitly override these with the correct subdocument types if they need those. See here: https://mongoosejs.com/docs/typescript/subdocuments.html. This allows users to be able to set a subdocument to a plain JS object without JS complaining, and then under the hood Mongoose manually converts the JS object to a subdocument. I dont really like that solution because its incorrectly typing the subdocument on the schema, its missing all the helper methods that a usual subdocument would have. The types generated by mongoose-tsgen are more correct, but the downside is they prevent you from using the shorthand form mentioned above. I'd actually argue this is actually good thing, it enforces more explicit code which makes clear that you aren't overwriting a subdocument with a plain JS object. And according to the Mongoose docs, the recommended way to create subdoc arrays is with the // If you want to overwrite the whole subdoc, like you were doing before, use create:
const venue = await VenueModel.findById(venueId);
const openingHour = venue.openingHours.create({
day: 'Monday',
active: true,
openingTime: "09:00",
closingTime: "17:00",
});
venue.openingHours = [openingHour]
// Or to just append a document (even if the openingHours list is empty):
venue.openingHours.push({
day: 'Monday',
active: true,
openingTime: "09:00",
closingTime: "17:00",
}); Now I'd rather make mongoose-tsgen more flexible rather than less, and don't like impose coding structure on existing repos, but I dont see any way to accomplish this request without forgoing type safety. The only thing that could accomplish it without reducing type safety is if Typescript had a way to define a type for setting a field, and a different type for getting the same field, but I haven't seen anything like that |
Let me know your thoughts @Dezzymei @maxshugar, happy to explore other options if you have any ideas, otherwise will close this out if the solution above works |
Thanks @francescov1, I don't mind not using the short hand form. |
Hello! I am having issues trying to create a new Document in ts (it works fine in js).
"mongoose": "^5.11.10",
"mongoose-tsgen": "7.1.3",
node: v16.15.1
npm: v8.11.0
tsc: Version 4.9.3
Schema
user.ts
:I get this in my
types.gen.ts
:I want to create it in my router:
This throws an error:
Type 'UserTikTokAdvertiserAccount[]' is missing the following properties from type 'DocumentArray<UserTikTokAdvertiserAccountDocument>': isMongooseDocumentArray, create, id, $pop, and 8 more.
So my question is how do I create this DocumentArray?
Interestingly if I try:
it seems to work out fine without Typescript complaining.
But if I try something on multiple lines then typescript gets confused:
Type 'DocumentArray<Document<any, any, any>>' is not assignable to type 'DocumentArray<UserTikTokAdvertiserAccountDocument>'. Type 'Document<any, any, any>' is missing the following properties from type 'UserTikTokAdvertiserAccountDocument': ownerDocument, parent, parentArray
So my question is how should I create these sub document arrays on this user document?
The text was updated successfully, but these errors were encountered: