Skip to content

Commit da37597

Browse files
committed
feat: add AutoInferredSchema to work around schema inference issues in #14954
1 parent f34935d commit da37597

File tree

4 files changed

+57
-7
lines changed

4 files changed

+57
-7
lines changed

lib/mongoose.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,15 @@ Mongoose.prototype.Mongoose = Mongoose;
937937

938938
Mongoose.prototype.Schema = Schema;
939939

940+
/**
941+
* Identical to `Schema` at runtime. Exists purely to work around some TypeScript compatibility issues.
942+
*
943+
* @method AutoInferredSchema
944+
* @api public
945+
*/
946+
947+
Mongoose.prototype.AutoInferredSchema = Schema;
948+
940949
/**
941950
* The Mongoose [SchemaType](https://mongoosejs.com/docs/api/schematype.html#SchemaType()) constructor
942951
*

test/types/inferrawdoctype.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InferRawDocType } from 'mongoose';
1+
import { InferRawDocType, Schema, AutoInferredSchema } from 'mongoose';
22
import { expectType, expectError } from 'tsd';
33

44
function gh14839() {
@@ -17,9 +17,22 @@ function gh14839() {
1717
dateOfBirth: {
1818
type: Date,
1919
required: true
20-
}
20+
},
21+
subdoc: new AutoInferredSchema({
22+
name: { type: String, required: true },
23+
l2: new AutoInferredSchema({
24+
myProp: { type: Number, required: true }
25+
})
26+
}),
27+
docArr: [new AutoInferredSchema({ test: { type: String, required: true } })]
2128
};
2229

23-
type UserType = InferRawDocType< typeof schemaDefinition>;
24-
expectType<{ email: string, password: string, dateOfBirth: Date }>({} as UserType);
30+
type UserType = InferRawDocType<typeof schemaDefinition>;
31+
expectType<{
32+
email: string,
33+
password: string,
34+
dateOfBirth: Date,
35+
subdoc?: { name: string, l2?: { myProp: number } | null } | null,
36+
docArr: { test: string }[]
37+
}>({} as UserType);
2538
}

types/index.d.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,29 @@ declare module 'mongoose' {
252252
TVirtuals,
253253
TStaticMethods> = (schema: Schema<DocType, M, TInstanceMethods, TQueryHelpers, TVirtuals, TStaticMethods>, opts?: any) => void;
254254

255+
export class AutoInferredSchema<
256+
SchemaDef = unknown,
257+
RawDocType = any,
258+
TModelType = Model<RawDocType, any, any, any>,
259+
TInstanceMethods = {},
260+
TQueryHelpers = {},
261+
TVirtuals = {},
262+
TStaticMethods = {},
263+
TSchemaOptions = DefaultSchemaOptions,
264+
DocType extends ApplySchemaOptions<
265+
ObtainDocumentType<DocType, RawDocType, ResolveSchemaOptions<TSchemaOptions>>,
266+
ResolveSchemaOptions<TSchemaOptions>
267+
> = ApplySchemaOptions<
268+
ObtainDocumentType<any, RawDocType, ResolveSchemaOptions<TSchemaOptions>>,
269+
ResolveSchemaOptions<TSchemaOptions>
270+
>,
271+
THydratedDocumentType = HydratedDocument<FlatRecord<DocType>, TVirtuals & TInstanceMethods>
272+
> extends Schema<RawDocType, TModelType, TInstanceMethods, TQueryHelpers, TVirtuals, TStaticMethods, TSchemaOptions, DocType, THydratedDocumentType> {
273+
constructor(definition?: SchemaDef, options?: SchemaOptions<FlatRecord<DocType>, TInstanceMethods, TQueryHelpers, TStaticMethods, TVirtuals, THydratedDocumentType> | ResolveSchemaOptions<TSchemaOptions>);
274+
275+
_schemaDefinition: SchemaDef;
276+
}
277+
255278
export class Schema<
256279
RawDocType = any,
257280
TModelType = Model<RawDocType, any, any, any>,

types/inferrawdoctype.d.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
PathWithTypePropertyBaseType,
77
PathEnumOrString
88
} from './inferschematype';
9+
import { InferSchemaType } from 'mongoose';
910

1011
declare module 'mongoose' {
1112
export type InferRawDocType<
@@ -35,6 +36,10 @@ declare module 'mongoose' {
3536
TypeKey
3637
>;
3738

39+
type InferRawDocTypeFromSchema<TSchema extends Schema> = TSchema extends AutoInferredSchema
40+
? InferRawDocType<TSchema['_schemaDefinition']>
41+
: InferSchemaType<TSchema>;
42+
3843
/**
3944
* Same as inferSchemaType, except:
4045
*
@@ -50,11 +55,11 @@ declare module 'mongoose' {
5055
*/
5156
type ResolveRawPathType<PathValueType, Options extends SchemaTypeOptions<PathValueType> = {}, TypeKey extends string = DefaultSchemaOptions['typeKey']> =
5257
PathValueType extends Schema ?
53-
InferSchemaType<PathValueType> :
58+
InferRawDocTypeFromSchema<PathValueType> :
5459
PathValueType extends (infer Item)[] ?
5560
IfEquals<Item, never, any[], Item extends Schema ?
5661
// If Item is a schema, infer its type.
57-
Array<InferSchemaType<Item>> :
62+
Array<InferRawDocTypeFromSchema<Item>> :
5863
Item extends Record<TypeKey, any> ?
5964
Item[TypeKey] extends Function | String ?
6065
// If Item has a type key that's a string or a callable, it must be a scalar,
@@ -73,7 +78,7 @@ declare module 'mongoose' {
7378
>:
7479
PathValueType extends ReadonlyArray<infer Item> ?
7580
IfEquals<Item, never, any[], Item extends Schema ?
76-
Array<InferSchemaType<Item>> :
81+
Array<InferRawDocTypeFromSchema<Item>> :
7782
Item extends Record<TypeKey, any> ?
7883
Item[TypeKey] extends Function | String ?
7984
ObtainRawDocumentPathType<Item, TypeKey>[] :

0 commit comments

Comments
 (0)