Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions test/schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
20 changes: 20 additions & 0 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
DefaultSchemaOptions,
HydratedArraySubdocument,
HydratedSingleSubdocument,
Schema,
Document,
Expand Down Expand Up @@ -1555,3 +1556,22 @@ function gh14696() {
});

}

function gh14748() {
const nestedSchema = new Schema({ name: String });

const schema = new Schema({
arr: [nestedSchema],
singleNested: nestedSchema
});

const subdoc = schema.path('singleNested')
.cast<HydratedArraySubdocument<{ name: string }>>({ name: 'bar' });
expectAssignable<{ name: string }>(subdoc);

const subdoc2 = schema.path('singleNested').cast({ name: 'bar' });
expectAssignable<{ name: string }>(subdoc2);

const subdoc3 = schema.path<Schema.Types.Subdocument<{ name: string }>>('singleNested').cast({ name: 'bar' });
expectAssignable<{ name: string }>(subdoc3);
}
7 changes: 5 additions & 2 deletions types/schematypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ declare module 'mongoose' {
OptionsConstructor: SchemaTypeOptions<T>;

/** Cast `val` to this schema type. Each class that inherits from schema type should implement this function. */
cast(val: any, doc: Document<any>, init: boolean, prev?: any, options?: any): any;
cast(val: any, doc?: Document<any>, init?: boolean, prev?: any, options?: any): any;
cast<ResultType>(val: any, doc?: Document<any>, init?: boolean, prev?: any, options?: any): ResultType;

/** Sets a default value for this SchemaType. */
default(val: any): any;
Expand Down Expand Up @@ -443,7 +444,7 @@ declare module 'mongoose' {
defaultOptions: Record<string, any>;
}

class Subdocument extends SchemaType implements AcceptsDiscriminator {
class Subdocument<DocType = unknown> extends SchemaType implements AcceptsDiscriminator {
/** This schema type's name, to defend against minifiers that mangle function names. */
static schemaName: string;

Expand All @@ -455,6 +456,8 @@ declare module 'mongoose' {

discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string): U;
discriminator<D>(name: string | number, schema: Schema, value?: string): Model<D>;

cast(val: any, doc?: Document<any>, init?: boolean, prev?: any, options?: any): HydratedSingleSubdocument<DocType>;
}

class String extends SchemaType {
Expand Down