diff --git a/test/schema.test.js b/test/schema.test.js index 8cd58ba7b9f..3076c9df62a 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -3258,4 +3258,24 @@ describe('schema', function() { await q; }); + + it('supports casting object to subdocument (gh-14748) (gh-9076)', function() { + const nestedSchema = new Schema({ name: String }); + nestedSchema.methods.getAnswer = () => 42; + + const schema = new Schema({ + arr: [nestedSchema], + singleNested: nestedSchema + }); + + // Cast to doc array + let subdoc = schema.path('arr').cast([{ name: 'foo' }])[0]; + assert.ok(subdoc instanceof mongoose.Document); + assert.equal(subdoc.getAnswer(), 42); + + // Cast to single nested subdoc + subdoc = schema.path('singleNested').cast({ name: 'bar' }); + assert.ok(subdoc instanceof mongoose.Document); + assert.equal(subdoc.getAnswer(), 42); + }); }); diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 9dab60d2022..e3771e0dd64 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -1,5 +1,6 @@ import { DefaultSchemaOptions, + HydratedArraySubdocument, HydratedSingleSubdocument, Schema, Document, @@ -1555,3 +1556,17 @@ function gh14696() { }); } + +function gh14748() { + const nestedSchema = new Schema({ name: String }); + + const schema = new Schema({ + arr: [nestedSchema], + singleNested: nestedSchema + }); + + // Cast to single nested subdoc + const subdoc = schema.path('singleNested') + .cast>({ name: 'bar' }); + expectAssignable<{ name: string }>(subdoc); +} \ No newline at end of file diff --git a/types/schematypes.d.ts b/types/schematypes.d.ts index b7f1fc733b9..26eab700a81 100644 --- a/types/schematypes.d.ts +++ b/types/schematypes.d.ts @@ -220,7 +220,8 @@ declare module 'mongoose' { OptionsConstructor: SchemaTypeOptions; /** Cast `val` to this schema type. Each class that inherits from schema type should implement this function. */ - cast(val: any, doc: Document, init: boolean, prev?: any, options?: any): any; + cast(val: any, doc?: Document, init?: boolean, prev?: any, options?: any): any; + cast(val: any, doc?: Document, init?: boolean, prev?: any, options?: any): ResultType; /** Sets a default value for this SchemaType. */ default(val: any): any;