diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 97f358991ac..6843e12cfaa 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -429,7 +429,7 @@ export function autoTypedSchema() { mixed3: Schema.Types.Mixed, objectId1: Schema.Types.ObjectId, objectId2: 'ObjectId', - objectId3: 'objectId', + objectId3: 'ObjectID', customSchema: Int8, map1: { type: Map, of: String }, map2: { type: Map, of: Number }, @@ -540,7 +540,7 @@ export type AutoTypedSchemaType = { favoritDrink?: 'Tea' | 'Coffee', favoritColorMode: 'dark' | 'light' friendID?: Types.ObjectId; - nestedArray: Array<{ + nestedArray: Types.DocumentArray<{ date: Date; messages?: number; }> @@ -630,3 +630,75 @@ function gh11987() { expectError(userSchema.path<'foo'>('name')); expectType>(userSchema.path<'name'>('name').OptionsConstructor); } + +function gh12030() { + const Schema1 = new Schema({ + users: [ + { + username: { type: String } + } + ] + }); + + expectType<{ + users: { + username?: string + }[]; + }>({} as InferSchemaType); + + const Schema2 = new Schema({ + createdAt: { type: Date, default: Date.now } + }); + + expectType<{ createdAt: Date }>({} as InferSchemaType); + + const Schema3 = new Schema({ + users: [ + new Schema({ + username: { type: String }, + credit: { type: Number, default: 0 } + }) + ] + }); + + expectType<{ + users: Types.DocumentArray<{ + credit: number; + username?: string; + }>; + }>({} as InferSchemaType); + + + const Schema4 = new Schema({ + data: { type: { role: String }, default: {} } + }); + + expectType<{ data: { role?: string } }>({} as InferSchemaType); + + const Schema5 = new Schema({ + data: { type: { role: Object }, default: {} } + }); + + expectType<{ data: { role?: any } }>({} as InferSchemaType); + + const Schema6 = new Schema({ + track: { + backupCount: { + type: Number, + default: 0 + }, + count: { + type: Number, + default: 0 + } + } + }); + + expectType<{ + track?: { + backupCount: number; + count: number; + }; + }>({} as InferSchemaType); + +} diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index ce94e6221c0..b32a97b9ef7 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -1,4 +1,18 @@ -import { Schema, InferSchemaType, SchemaType, SchemaTypeOptions, TypeKeyBaseType, Types, NumberSchemaDefinition, StringSchemaDefinition, BooleanSchemaDefinition, DateSchemaDefinition } from 'mongoose'; +import { + Schema, + InferSchemaType, + SchemaType, + SchemaTypeOptions, + TypeKeyBaseType, + Types, + NumberSchemaDefinition, + StringSchemaDefinition, + BooleanSchemaDefinition, + DateSchemaDefinition, + ObtainDocumentType, + DefaultTypeKey, + ObjectIdSchemaDefinition +} from 'mongoose'; declare module 'mongoose' { /** @@ -75,9 +89,9 @@ type IsPathRequired = ? P extends { default: undefined } ? false : true - : P extends (Record) - ? P extends { default: ResolvePathType } - ? true + : P extends (Record) + ? P extends { default: any } + ? IfEquals : false : false; @@ -138,7 +152,8 @@ type ObtainDocumentPathType = Pa ? InferSchemaType : ResolvePathType< PathValueType extends PathWithTypePropertyBaseType ? PathValueType[TypeKey] : PathValueType, - PathValueType extends PathWithTypePropertyBaseType ? Omit : {} + PathValueType extends PathWithTypePropertyBaseType ? Omit : {}, + TypeKey >; /** @@ -151,17 +166,18 @@ type PathEnumOrString['enum']> = T extends ( * @summary Resolve path type by returning the corresponding type. * @param {PathValueType} PathValueType Document definition path type. * @param {Options} Options Document definition path options except path type. - * @returns Number, "Number" or "number" will be resolved to string type. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". + * @returns Number, "Number" or "number" will be resolved to number type. */ -type ResolvePathType = {}> = +type ResolvePathType = {}, TypeKey extends TypeKeyBaseType = DefaultTypeKey> = PathValueType extends Schema ? InferSchemaType : - PathValueType extends (infer Item)[] ? IfEquals>[] : + PathValueType extends (infer Item)[] ? IfEquals> : ResolvePathType[]> : PathValueType extends StringSchemaDefinition ? PathEnumOrString : PathValueType extends NumberSchemaDefinition ? number : PathValueType extends DateSchemaDefinition ? Date : PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer : PathValueType extends BooleanSchemaDefinition ? boolean : - PathValueType extends 'objectId' | 'ObjectId' | typeof Schema.Types.ObjectId ? Types.ObjectId : + PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId : PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 : PathValueType extends MapConstructor ? Map> : PathValueType extends ArrayConstructor ? any[] : @@ -169,5 +185,5 @@ type ResolvePathType extends true ? any: IfEquals extends true ? any: PathValueType extends typeof SchemaType ? PathValueType['prototype'] : - PathValueType extends {} ? PathValueType : + PathValueType extends Record ? ObtainDocumentType : unknown;