Skip to content

Commit

Permalink
Merge pull request #14756 from Automattic/vkarpov15/gh-14748
Browse files Browse the repository at this point in the history
types: allow calling `SchemaType.cast()` without `parent` and `init` parameters
  • Loading branch information
vkarpov15 authored Jul 26, 2024
2 parents b51a730 + 351b289 commit 2badd9e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
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

0 comments on commit 2badd9e

Please sign in to comment.