diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 3bfa731eea6..96b44f0d2c4 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -2,7 +2,6 @@ import { Schema, Document, SchemaDefinition, - SchemaDefinitionProperty, SchemaTypeOptions, Model, Types, @@ -358,14 +357,17 @@ export function autoTypedSchema() { string2?: string; string3?: string; string4?: string; + string5: string; number1?: number; number2?: number; number3?: number; number4?: number; + number5: number; date1?: Date; date2?: Date; date3?: Date; date4?: Date; + date5: Date; buffer1?: Buffer; buffer2?: Buffer; buffer3?: Buffer; @@ -374,23 +376,26 @@ export function autoTypedSchema() { boolean2?: boolean; boolean3?: boolean; boolean4?: boolean; + boolean5: boolean; mixed1?: any; mixed2?: any; mixed3?: any; - objectId1?: Schema.Types.ObjectId; - objectId2?: Schema.Types.ObjectId; - objectId3?: Schema.Types.ObjectId; + objectId1?: Types.ObjectId; + objectId2?: Types.ObjectId; + objectId3?: Types.ObjectId; customSchema?: Int8; map1?: Map; map2?: Map; - array1?: string[]; - array2?: any[]; - array3?: any[]; - array4?: any[]; - array5?: any[]; - decimal1?: Schema.Types.Decimal128; - decimal2?: Schema.Types.Decimal128; - decimal3?: Schema.Types.Decimal128; + array1: string[]; + array2: any[]; + array3: any[]; + array4: any[]; + array5: any[]; + array6: string[]; + array7?: string[]; + decimal1?: Types.Decimal128; + decimal2?: Types.Decimal128; + decimal3?: Types.Decimal128; }; const TestSchema = new Schema({ @@ -398,14 +403,17 @@ export function autoTypedSchema() { string2: 'String', string3: 'string', string4: Schema.Types.String, + string5: { type: String, default: 'ABCD' }, number1: Number, number2: 'Number', number3: 'number', number4: Schema.Types.Number, + number5: { type: Number, default: 10 }, date1: Date, date2: 'Date', date3: 'date', date4: Schema.Types.Date, + date5: { type: Date, default: new Date() }, buffer1: Buffer, buffer2: 'Buffer', buffer3: 'buffer', @@ -414,6 +422,7 @@ export function autoTypedSchema() { boolean2: 'Boolean', boolean3: 'boolean', boolean4: Schema.Types.Boolean, + boolean5: { type: Boolean, default: true }, mixed1: Object, mixed2: {}, mixed3: Schema.Types.Mixed, @@ -428,6 +437,8 @@ export function autoTypedSchema() { array3: [Schema.Types.Mixed], array4: [{}], array5: [], + array6: { type: [String] }, + array7: { type: [String], default: undefined }, decimal1: Schema.Types.Decimal128, decimal2: 'Decimal128', decimal3: 'decimal128' @@ -475,6 +486,17 @@ export function autoTypedSchema() { message: '{VALUE} is not supported' }, required: true + }, + friendID: { + type: Schema.Types.ObjectId + }, + nestedArray: { + type: [ + new Schema({ + date: { type: Date, required: true }, + messages: Number + }) + ] } }, { statics: { @@ -516,6 +538,11 @@ export type AutoTypedSchemaType = { }, favoritDrink?: 'Tea' | 'Coffee', favoritColorMode: 'dark' | 'light' + friendID?: Types.ObjectId; + nestedArray: Array<{ + date: Date; + messages?: number; + }> } , statics: { staticFn: () => 'Returned from staticFn' diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index df2fd0ce728..ce94e6221c0 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -1,4 +1,4 @@ -import { Schema, InferSchemaType, SchemaType, SchemaTypeOptions, TypeKeyBaseType } from 'mongoose'; +import { Schema, InferSchemaType, SchemaType, SchemaTypeOptions, TypeKeyBaseType, Types, NumberSchemaDefinition, StringSchemaDefinition, BooleanSchemaDefinition, DateSchemaDefinition } from 'mongoose'; declare module 'mongoose' { /** @@ -6,13 +6,13 @@ declare module 'mongoose' { * @description Obtains document schema type from document Definition OR returns enforced schema type if it's provided. * @param {DocDefinition} DocDefinition A generic equals to the type of document definition "provided in as first parameter in Schema constructor". * @param {EnforcedDocType} EnforcedDocType A generic type enforced by user "provided before schema constructor". - * @param {TypeKey} TypeKey A generic of literal string type. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". */ - type ObtainDocumentType = - IsItRecordAndNotAny extends true ? EnforcedDocType : { - [K in keyof (RequiredPaths & - OptionalPaths)]: ObtainDocumentPathType; - }; + type ObtainDocumentType = + IsItRecordAndNotAny extends true ? EnforcedDocType : { + [K in keyof (RequiredPaths & + OptionalPaths)]: ObtainDocumentPathType; + }; /** * @summary Obtains document schema type from Schema instance. @@ -64,10 +64,22 @@ type IfEquals = (() => G extends U ? 1 : 0) ? Y : N; /** - * @summary Required path base type. - * @description It helps to check whereas if a path is required OR optional. + * @summary Checks if a document path is required or optional. + * @param {P} P Document path. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". */ -type RequiredPathBaseType = { required: true | [true, string | undefined] }; +type IsPathRequired = + P extends { required: true | [true, string | undefined] } | ArrayConstructor | any[] + ? true + : P extends (Record) + ? P extends { default: undefined } + ? false + : true + : P extends (Record) + ? P extends { default: ResolvePathType } + ? true + : false + : false; /** * @summary Path base type defined by using TypeKey @@ -79,37 +91,41 @@ type PathWithTypePropertyBaseType = { [k in Typ /** * @summary A Utility to obtain schema's required path keys. * @param {T} T A generic refers to document definition. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns required paths keys of document definition. */ -type RequiredPathKeys = { - [K in keyof T]: T[K] extends RequiredPathBaseType ? IfEquals : never; +type RequiredPathKeys = { + [K in keyof T]: IsPathRequired extends true ? IfEquals : never; }[keyof T]; /** * @summary A Utility to obtain schema's required paths. * @param {T} T A generic refers to document definition. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns a record contains required paths with the corresponding type. */ -type RequiredPaths = { - [K in RequiredPathKeys]: T[K]; +type RequiredPaths = { + [K in RequiredPathKeys]: T[K]; }; /** * @summary A Utility to obtain schema's optional path keys. * @param {T} T A generic refers to document definition. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns optional paths keys of document definition. */ -type OptionalPathKeys = { - [K in keyof T]: T[K] extends RequiredPathBaseType ? never : K; +type OptionalPathKeys = { + [K in keyof T]: IsPathRequired extends true ? never : K; }[keyof T]; /** * @summary A Utility to obtain schema's optional paths. * @param {T} T A generic refers to document definition. + * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition". * @returns a record contains optional paths with the corresponding type. */ -type OptionalPaths = { - [K in OptionalPathKeys]?: T[K]; +type OptionalPaths = { + [K in OptionalPathKeys]?: T[K]; }; /** @@ -138,18 +154,20 @@ type PathEnumOrString['enum']> = T extends ( * @returns Number, "Number" or "number" will be resolved to string type. */ type ResolvePathType = {}> = - PathValueType extends (infer Item)[] ? IfEquals>[] : - PathValueType extends StringConstructor | 'string' | 'String' | typeof Schema.Types.String ? PathEnumOrString : - PathValueType extends NumberConstructor | 'number' | 'Number' | typeof Schema.Types.Number ? number : - PathValueType extends DateConstructor | 'date' | 'Date' | typeof Schema.Types.Date ? Date : - PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer : - PathValueType extends BooleanConstructor | 'boolean' | 'Boolean' | typeof Schema.Types.Boolean ? boolean : - PathValueType extends 'objectId' | 'ObjectId' | typeof Schema.Types.ObjectId ? Schema.Types.ObjectId : - PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Schema.Types.Decimal128 : - PathValueType extends MapConstructor ? Map> : - PathValueType extends ArrayConstructor ? any[] : - PathValueType extends typeof Schema.Types.Mixed ? any: - IfEquals extends true ? any: - IfEquals extends true ? any: - PathValueType extends typeof SchemaType ? PathValueType['prototype'] : - unknown; + PathValueType extends Schema ? InferSchemaType : + PathValueType extends (infer Item)[] ? IfEquals>[] : + 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 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 : + PathValueType extends MapConstructor ? Map> : + PathValueType extends ArrayConstructor ? any[] : + PathValueType extends typeof Schema.Types.Mixed ? any: + IfEquals extends true ? any: + IfEquals extends true ? any: + PathValueType extends typeof SchemaType ? PathValueType['prototype'] : + PathValueType extends {} ? PathValueType : + unknown;