Skip to content

Commit 2badd9e

Browse files
authored
Merge pull request #14756 from Automattic/vkarpov15/gh-14748
types: allow calling `SchemaType.cast()` without `parent` and `init` parameters
2 parents b51a730 + 351b289 commit 2badd9e

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

test/schema.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,4 +3258,24 @@ describe('schema', function() {
32583258

32593259
await q;
32603260
});
3261+
3262+
it('supports casting object to subdocument (gh-14748) (gh-9076)', function() {
3263+
const nestedSchema = new Schema({ name: String });
3264+
nestedSchema.methods.getAnswer = () => 42;
3265+
3266+
const schema = new Schema({
3267+
arr: [nestedSchema],
3268+
singleNested: nestedSchema
3269+
});
3270+
3271+
// Cast to doc array
3272+
let subdoc = schema.path('arr').cast([{ name: 'foo' }])[0];
3273+
assert.ok(subdoc instanceof mongoose.Document);
3274+
assert.equal(subdoc.getAnswer(), 42);
3275+
3276+
// Cast to single nested subdoc
3277+
subdoc = schema.path('singleNested').cast({ name: 'bar' });
3278+
assert.ok(subdoc instanceof mongoose.Document);
3279+
assert.equal(subdoc.getAnswer(), 42);
3280+
});
32613281
});

test/types/schema.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
DefaultSchemaOptions,
3+
HydratedArraySubdocument,
34
HydratedSingleSubdocument,
45
Schema,
56
Document,
@@ -1555,3 +1556,22 @@ function gh14696() {
15551556
});
15561557

15571558
}
1559+
1560+
function gh14748() {
1561+
const nestedSchema = new Schema({ name: String });
1562+
1563+
const schema = new Schema({
1564+
arr: [nestedSchema],
1565+
singleNested: nestedSchema
1566+
});
1567+
1568+
const subdoc = schema.path('singleNested')
1569+
.cast<HydratedArraySubdocument<{ name: string }>>({ name: 'bar' });
1570+
expectAssignable<{ name: string }>(subdoc);
1571+
1572+
const subdoc2 = schema.path('singleNested').cast({ name: 'bar' });
1573+
expectAssignable<{ name: string }>(subdoc2);
1574+
1575+
const subdoc3 = schema.path<Schema.Types.Subdocument<{ name: string }>>('singleNested').cast({ name: 'bar' });
1576+
expectAssignable<{ name: string }>(subdoc3);
1577+
}

types/schematypes.d.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ declare module 'mongoose' {
220220
OptionsConstructor: SchemaTypeOptions<T>;
221221

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

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

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

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

456457
discriminator<T, U>(name: string | number, schema: Schema<T, U>, value?: string): U;
457458
discriminator<D>(name: string | number, schema: Schema, value?: string): Model<D>;
459+
460+
cast(val: any, doc?: Document<any>, init?: boolean, prev?: any, options?: any): HydratedSingleSubdocument<DocType>;
458461
}
459462

460463
class String extends SchemaType {

0 commit comments

Comments
 (0)