diff --git a/lib/schema.js b/lib/schema.js index 600e27208ee..433d3cf036e 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -1268,6 +1268,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) { return clone; } + // If this schema has an associated Mongoose object, use the Mongoose object's // copy of SchemaTypes re: gh-7158 gh-6933 const MongooseTypes = this.base != null ? this.base.Schema.Types : Schema.Types; @@ -1333,9 +1334,13 @@ Schema.prototype.interpretAsType = function(path, obj, options) { } return new MongooseTypes.DocumentArray(path, cast[options.typeKey], obj, cast); } - - if (Array.isArray(cast)) { - return new MongooseTypes.Array(path, this.interpretAsType(path, cast, options), obj); + if (typeof cast !== 'undefined') { + if (Array.isArray(cast) || cast.type === Array || cast.type == 'Array') { + if (cast && cast.type == 'Array') { + cast.type = Array; + } + return new MongooseTypes.Array(path, this.interpretAsType(path, cast, options), obj); + } } // Handle both `new Schema({ arr: [{ subpath: String }] })` and `new Schema({ arr: [{ type: { subpath: string } }] })` @@ -1386,7 +1391,6 @@ Schema.prototype.interpretAsType = function(path, obj, options) { type = cast[options.typeKey] && (options.typeKey !== 'type' || !cast.type.type) ? cast[options.typeKey] : cast; - if (Array.isArray(type)) { return new MongooseTypes.Array(path, this.interpretAsType(path, type, options), obj); } diff --git a/test/schema.test.js b/test/schema.test.js index 0df19a65790..61f206d6f0f 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -3202,4 +3202,14 @@ describe('schema', function() { const doc = new baseModel({ type: 1, self: [{ type: 1 }] }); assert.equal(doc.self[0].type, 1); }); + it('should have the correct schema definition with array schemas (gh-14416)', function() { + const schema = new Schema({ + nums: [{ type: Array, of: Number }], + tags: [{ type: 'Array', of: String }], + subdocs: [{ type: Array, of: Schema({ name: String }) }] + }); + assert.equal(schema.path('nums.$').caster.instance, 'Number'); // actually Mixed + assert.equal(schema.path('tags.$').caster.instance, 'String'); // actually Mixed + assert.equal(schema.path('subdocs.$').casterConstructor.schema.path('name').instance, 'String'); // actually Mixed + }); });