From 8c1070f36998bd1dfe1ed4c236a08f627f265905 Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Sat, 2 Jul 2022 02:48:57 +0200 Subject: [PATCH 1/8] Add some TS tests related to the issue: 12030 --- test/types/schema.test.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 97f358991ac..4312d321d6c 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -630,3 +630,39 @@ 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: 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<{ userName?: string, credit: number }> }>({} as InferSchemaType); + + + const Schema4 = new Schema({ + data: { type: { role: String }, default: {} } + }); + + // expectType<{ data: { role?: string } }>({} as InferSchemaType); +} From 01c556a9154a69f9d8a30f965496e76fd2fee461 Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 00:38:34 +0200 Subject: [PATCH 2/8] Add more tests. --- test/types/schema.test.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 4312d321d6c..9006dcffa9c 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -665,4 +665,31 @@ function gh12030() { }); // expectType<{ data: { role?: string } }>({} as InferSchemaType); + + const Schema5 = new Schema({ + data: { type: { role: Object }, default: {} } + }); + + // expectType<{ data: { role?: string } }>({} 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); + } From d092fdcf06cf3063e2d35530676c00f2af4edbfb Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 00:39:14 +0200 Subject: [PATCH 3/8] Fix one case of the reported issues. --- types/inferschematype.d.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index ce94e6221c0..0b2c6eb792b 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -1,4 +1,17 @@ -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 +} from 'mongoose'; declare module 'mongoose' { /** @@ -138,7 +151,8 @@ type ObtainDocumentPathType = Pa ? InferSchemaType : ResolvePathType< PathValueType extends PathWithTypePropertyBaseType ? PathValueType[TypeKey] : PathValueType, - PathValueType extends PathWithTypePropertyBaseType ? Omit : {} + PathValueType extends PathWithTypePropertyBaseType ? Omit : {}, + TypeKey >; /** @@ -153,7 +167,7 @@ type PathEnumOrString['enum']> = T extends ( * @param {Options} Options Document definition path options except path type. * @returns Number, "Number" or "number" will be resolved to string type. */ -type ResolvePathType = {}> = +type ResolvePathType = {}, TypeKey extends TypeKeyBaseType = DefaultTypeKey> = PathValueType extends Schema ? InferSchemaType : PathValueType extends (infer Item)[] ? IfEquals>[] : PathValueType extends StringSchemaDefinition ? PathEnumOrString : @@ -169,5 +183,5 @@ type ResolvePathType extends true ? any: IfEquals extends true ? any: PathValueType extends typeof SchemaType ? PathValueType['prototype'] : - PathValueType extends {} ? PathValueType : + PathValueType extends Record ? ObtainDocumentType : unknown; From 99aaba095691cf36e795739debc31411cdfea602 Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 00:40:28 +0200 Subject: [PATCH 4/8] Refactor --- types/inferschematype.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index 0b2c6eb792b..d3fb5fe32c5 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -165,6 +165,7 @@ 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. + * @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 string type. */ type ResolvePathType = {}, TypeKey extends TypeKeyBaseType = DefaultTypeKey> = From 5f9f79c224e2df6a9c5c5ba0ab80a5991ec8cafe Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 01:38:46 +0200 Subject: [PATCH 5/8] Refactor a test --- test/types/schema.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 9006dcffa9c..082e576ab08 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -640,7 +640,11 @@ function gh12030() { ] }); - // expectType<{ users: string[] }>({} as InferSchemaType); + expectType<{ + users: { + username?: string + }[]; + }>({} as InferSchemaType); const Schema2 = new Schema({ createdAt: { type: Date, default: Date.now } From 3feb8af37c4d65bdc2e68b230882723c33cdfe7c Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 02:10:00 +0200 Subject: [PATCH 6/8] Refactor some lines in ResolvePathType helper related to objectId --- test/types/schema.test.ts | 2 +- types/inferschematype.d.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 082e576ab08..7706c5c6a3c 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 }, diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index d3fb5fe32c5..aa858c4f42d 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -10,7 +10,8 @@ import { BooleanSchemaDefinition, DateSchemaDefinition, ObtainDocumentType, - DefaultTypeKey + DefaultTypeKey, + ObjectIdSchemaDefinition } from 'mongoose'; declare module 'mongoose' { @@ -166,7 +167,7 @@ type PathEnumOrString['enum']> = T extends ( * @param {PathValueType} PathValueType Document definition path type. * @param {Options} Options Document definition path options except path 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 string type. + * @returns Number, "Number" or "number" will be resolved to number type. */ type ResolvePathType = {}, TypeKey extends TypeKeyBaseType = DefaultTypeKey> = PathValueType extends Schema ? InferSchemaType : @@ -176,7 +177,7 @@ type ResolvePathType> : PathValueType extends ArrayConstructor ? any[] : From a2ff5739c5c66c0cae70a33320b83480bdb87a6c Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 02:26:21 +0200 Subject: [PATCH 7/8] fix 2 more issues --- test/types/schema.test.ts | 6 +++--- types/inferschematype.d.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 7706c5c6a3c..f99251a641b 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -650,7 +650,7 @@ function gh12030() { createdAt: { type: Date, default: Date.now } }); - // expectType<{ createdAt: Date }>({} as InferSchemaType); + expectType<{ createdAt: Date }>({} as InferSchemaType); const Schema3 = new Schema({ users: [ @@ -668,13 +668,13 @@ function gh12030() { data: { type: { role: String }, default: {} } }); - // expectType<{ data: { role?: string } }>({} as InferSchemaType); + expectType<{ data: { role?: string } }>({} as InferSchemaType); const Schema5 = new Schema({ data: { type: { role: Object }, default: {} } }); - // expectType<{ data: { role?: string } }>({} as InferSchemaType); + expectType<{ data: { role?: string } }>({} as InferSchemaType); const Schema6 = new Schema({ track: { diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index aa858c4f42d..1cf0cf91bae 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -89,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; From 9128dbd28f2e29c4c22a789dce0ab569a505e1ae Mon Sep 17 00:00:00 2001 From: mohammad0-0ahmad Date: Mon, 4 Jul 2022 02:51:44 +0200 Subject: [PATCH 8/8] Infer nested schema array to Types.DocumentArray instead of normal array. --- test/types/schema.test.ts | 11 ++++++++--- types/inferschematype.d.ts | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index f99251a641b..6843e12cfaa 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -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; }> @@ -661,7 +661,12 @@ function gh12030() { ] }); - // expectType<{ users: Types.DocumentArray<{ userName?: string, credit: number }> }>({} as InferSchemaType); + expectType<{ + users: Types.DocumentArray<{ + credit: number; + username?: string; + }>; + }>({} as InferSchemaType); const Schema4 = new Schema({ @@ -674,7 +679,7 @@ function gh12030() { data: { type: { role: Object }, default: {} } }); - expectType<{ data: { role?: string } }>({} as InferSchemaType); + expectType<{ data: { role?: any } }>({} as InferSchemaType); const Schema6 = new Schema({ track: { diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index 1cf0cf91bae..b32a97b9ef7 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -171,7 +171,7 @@ type PathEnumOrString['enum']> = T extends ( */ 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 :