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
DocumentArray
constructor accepts array of any type what can cause runtime error
#13087
Comments
You're right, we should change |
@vkarpov15 Shouldn't it be |
No, because of type casting. For example, |
My use case is that I have an interface with required fields, and currently with DocumentArray it's possible to forget to add one of these fields what can result in an error: import { InferSchemaType, Schema, Types } from 'mongoose';
const locationSchema = new Schema(
{
type: {
required: true,
type: String,
enum: ['Point'],
},
coordinates: {
required: true,
type: [Number], // [longitude, latitude]
},
},
{ _id: false }
);
const pointSchema = new Schema({
name: { required: true, type: String },
location: { required: true, type: locationSchema },
});
const routeSchema = new Schema({
points: { type: [pointSchema] },
});
type Route = InferSchemaType<typeof routeSchema>;
function getTestRouteData(): Route {
return {
points: new Types.DocumentArray([
{ name: 'Test' } // "location" is missing
]),
};
}
const { points } = getTestRouteData();
points.forEach(({ location }) => {
console.log(`Point coordinates: ${location.coordinates[0]},${location.coordinates[1]}`);
});
// TypeError: Cannot read properties of undefined (reading 'coordinates') |
We'll work on a better workaround for this, but for now you can add const pointSchema = new Schema({
name: { required: true, type: String },
location: { required: true, type: locationSchema, default: () => ({}) }, // <-- `default` here
}); That gives you the TypeError that you expect:
|
Maybe I need to change something else additionally, because it works same way as before 😄 |
Weird. Well, at least if you add |
types(documentarray): typed DocumentArray constructor parameter
@vkarpov15 @lpizzinidev With
Code: import { InferSchemaType, Schema, Types } from 'mongoose';
const locationSchema = new Schema(
{
type: {
required: true,
type: String,
enum: ['Point'],
},
coordinates: {
required: true,
type: [Number], // [longitude, latitude]
},
},
{ _id: false }
);
const pointSchema = new Schema({
name: { required: true, type: String },
location: { required: true, type: locationSchema },
});
const routeSchema = new Schema({
points: { type: [pointSchema] },
});
type Route = InferSchemaType<typeof routeSchema>;
function getTestRouteData(): Route {
return {
points: new Types.DocumentArray([
{ name: 'Test', location: { type: 'Point', coordinates: [1, 2] } }
]),
};
}
const { points } = getTestRouteData();
points.forEach(({ location }) => {
console.log(`Point coordinates: ${location.coordinates[0]},${location.coordinates[1]}`);
}); |
@vkarpov15 I guess that |
types(documentarray): fixed type of DocumentArray constructor parameter
Prerequisites
Mongoose version
6.10.0
Node.js version
18.12.0
MongoDB server version
N/A
Typescript version (if applicable)
4.9.5
Description
DocumentArray
constructor acceptsvalues: any[]
:This can result in runtime error when passed to constructor value won't have required field.
Steps to Reproduce
This code compiles and results in runtime error:
Error:
Expected Behavior
Compile time error:
The text was updated successfully, but these errors were encountered: