From c384eb0667d827f7430d0e0ba758c3c3229a9426 Mon Sep 17 00:00:00 2001 From: Danila Stryzhonak Date: Thu, 1 Aug 2024 18:05:45 +0300 Subject: [PATCH] fix: inferSchemaType, inferRawType updates to infer based on provided schema options as well --- test/types/schema.test.ts | 29 +++++++++++++++++++++++++++++ types/inferrawdoctype.d.ts | 4 ++-- types/inferschematype.d.ts | 21 ++++++++++++++++----- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index a9679c082b8..2d946adc93c 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -1575,3 +1575,32 @@ function gh14748() { const subdoc3 = schema.path>('singleNested').cast({ name: 'bar' }); expectAssignable<{ name: string }>(subdoc3); } + +function gh13215() { + const schemaDefinition = { + userName: { type: String, required: true } + } as const; + const schemaOptions = { + typeKey: 'type', + timestamps: { + createdAt: 'date', + updatedAt: false + } + } as const; + + type RawDocType = InferRawDocType< + typeof schemaDefinition, + typeof schemaOptions + >; + type User = { + userName: string; + } & { + date: Date; + }; + + expectType({} as RawDocType); + + const schema = new Schema(schemaDefinition, schemaOptions); + type SchemaType = InferSchemaType; + expectType({} as SchemaType); +} diff --git a/types/inferrawdoctype.d.ts b/types/inferrawdoctype.d.ts index 95a912ff240..e2b1d52b6b9 100644 --- a/types/inferrawdoctype.d.ts +++ b/types/inferrawdoctype.d.ts @@ -10,12 +10,12 @@ declare module 'mongoose' { export type InferRawDocType< DocDefinition, TSchemaOptions extends Record = DefaultSchemaOptions - > = { + > = ApplySchemaOptions<{ [ K in keyof (RequiredPaths & OptionalPaths) ]: ObtainRawDocumentPathType; - }; + }, TSchemaOptions>; /** * @summary Obtains schema Path type. diff --git a/types/inferschematype.d.ts b/types/inferschematype.d.ts index ff1e92b7831..2bb6abf8bbe 100644 --- a/types/inferschematype.d.ts +++ b/types/inferschematype.d.ts @@ -74,14 +74,25 @@ declare module 'mongoose' { type ApplySchemaOptions = ResolveTimestamps; - type ResolveTimestamps = O extends { timestamps: true } + type ResolveTimestamps = O extends { methods: any } | { statics: any } | { virtuals: any } | { timestamps?: false } ? T // For some reason, TypeScript sets all the document properties to unknown // if we use methods, statics, or virtuals. So avoid inferring timestamps // if any of these are set for now. See gh-12807 - ? O extends { methods: any } | { statics: any } | { virtuals: any } - ? T - : { createdAt: NativeDate; updatedAt: NativeDate; } & T - : T; + : O extends { timestamps: infer TimestampOptions } ? TimestampOptions extends true + ? { createdAt: NativeDate; updatedAt: NativeDate; } & T + : TimestampOptions extends SchemaTimestampsConfig + ? { + -readonly [K in keyof Pick< + TimestampOptions, + 'createdAt' | 'updatedAt' + > as TimestampOptions[K] extends true + ? K + : TimestampOptions[K] extends string + ? TimestampOptions[K] + : never]: NativeDate; + } & T + : T + : T; } type IsPathDefaultUndefined = PathType extends { default: undefined } ?