Skip to content

Commit 8adc84d

Browse files
committed
types: avoid unnecessary MergeType<> if TOverrides not set, clean up statics and insertMany() type issues
Fix #13529
1 parent 9b82bf5 commit 8adc84d

File tree

4 files changed

+58
-39
lines changed

4 files changed

+58
-39
lines changed

test/types/models.test.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ObjectId } from 'bson';
21
import {
32
Schema,
43
Document,
@@ -77,7 +76,7 @@ async function insertManyTest() {
7776
});
7877

7978
const res = await Test.insertMany([{ foo: 'bar' }], { rawResult: true });
80-
expectType<ObjectId>(res.insertedIds[0]);
79+
expectType<Types.ObjectId>(res.insertedIds[0]);
8180

8281
const res2 = await Test.insertMany([{ foo: 'bar' }], { ordered: false, rawResult: true });
8382
expectAssignable<Error | Object | ReturnType<(typeof Test)['hydrate']>>(res2.mongoose.results[0]);
@@ -622,3 +621,21 @@ function gh13206() {
622621
expectType<ChangeStreamInsertDocument<ITest>>(change);
623622
});
624623
}
624+
625+
function gh13529() {
626+
interface ResourceDoc {
627+
foo: string;
628+
}
629+
630+
type ResourceIdT<ResourceIdField extends string> = {
631+
[key in ResourceIdField]: string;
632+
};
633+
type ResourceDocWithId<ResourceIdField extends string> = ResourceDoc & ResourceIdT<ResourceIdField>;
634+
635+
function test<
636+
ResourceType extends string,
637+
DocT extends ResourceDocWithId<`${ResourceType}Id`>>(dbModel: Model<DocT>) {
638+
const resourceDoc = new dbModel();
639+
resourceDoc.foo = 'bar';
640+
}
641+
}

types/index.d.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,12 @@ declare module 'mongoose' {
141141
> = IfAny<
142142
DocType,
143143
any,
144-
Document<unknown, TQueryHelpers, DocType> & MergeType<
145-
Require_id<DocType>,
146-
TOverrides extends Record<string, never> ?
147-
{} :
144+
TOverrides extends Record<string, never> ?
145+
Document<unknown, TQueryHelpers, DocType> & Require_id<DocType> :
146+
Document<unknown, TQueryHelpers, DocType> & MergeType<
147+
Require_id<DocType>,
148148
IfAny<TOverrides, {}>
149-
>
149+
>
150150
>;
151151
export type HydratedSingleSubdocument<DocType, TOverrides = {}> = Types.Subdocument<unknown> & Require_id<DocType> & TOverrides;
152152
export type HydratedArraySubdocument<DocType, TOverrides = {}> = Types.ArraySubdocument<unknown> & Require_id<DocType> & TOverrides;
@@ -212,7 +212,7 @@ declare module 'mongoose' {
212212

213213
export class Schema<
214214
EnforcedDocType = any,
215-
M = Model<EnforcedDocType, any, any, any>,
215+
TModelType = Model<EnforcedDocType, any, any, any>,
216216
TInstanceMethods = {},
217217
TQueryHelpers = {},
218218
TVirtuals = {},
@@ -311,7 +311,7 @@ declare module 'mongoose' {
311311
pathType(path: string): string;
312312

313313
/** Registers a plugin for this schema. */
314-
plugin<PFunc extends PluginFunction<DocType, M, any, any, any, any>, POptions extends Parameters<PFunc>[1] = Parameters<PFunc>[1]>(fn: PFunc, opts?: POptions): this;
314+
plugin<PFunc extends PluginFunction<DocType, TModelType, any, any, any, any>, POptions extends Parameters<PFunc>[1] = Parameters<PFunc>[1]>(fn: PFunc, opts?: POptions): this;
315315

316316
/** Defines a post hook for the model. */
317317

@@ -320,7 +320,7 @@ declare module 'mongoose' {
320320
post<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption<T>): this;
321321
post<T = THydratedDocumentType>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption<T>): this;
322322
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption<T, Array<any>>): this;
323-
post<T = M>(method: 'insertMany' | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption<T>): this;
323+
post<T = TModelType>(method: 'insertMany' | RegExp, options: SchemaPostOptions & { errorHandler: true }, fn: ErrorHandlingMiddlewareWithOption<T>): this;
324324

325325
// this = never since it never happens
326326
post<T = never>(method: MongooseQueryOrDocumentMiddleware | MongooseQueryOrDocumentMiddleware[] | RegExp, options: SchemaPostOptions & { document: false, query: false }, fn: PostMiddlewareFunction<never, never>): this;
@@ -358,14 +358,14 @@ declare module 'mongoose' {
358358
// method aggregate and insertMany with PostMiddlewareFunction
359359
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PostMiddlewareFunction<T, Array<AggregateExtract<T>>>): this;
360360
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, Array<AggregateExtract<T>>>): this;
361-
post<T = M>(method: 'insertMany' | RegExp, fn: PostMiddlewareFunction<T, T>): this;
362-
post<T = M>(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, T>): this;
361+
post<T = TModelType>(method: 'insertMany' | RegExp, fn: PostMiddlewareFunction<T, T>): this;
362+
post<T = TModelType>(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, T>): this;
363363

364364
// method aggregate and insertMany with ErrorHandlingMiddlewareFunction
365365
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: ErrorHandlingMiddlewareFunction<T, Array<any>>): this;
366366
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T, Array<any>>): this;
367-
post<T = M>(method: 'insertMany' | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
368-
post<T = M>(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T>): this;
367+
post<T = TModelType>(method: 'insertMany' | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
368+
post<T = TModelType>(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T>): this;
369369

370370
/** Defines a pre hook for the model. */
371371
// this = never since it never happens
@@ -390,8 +390,8 @@ declare module 'mongoose' {
390390
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PreMiddlewareFunction<T>): this;
391391
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
392392
/* method insertMany */
393-
pre<T = M>(method: 'insertMany' | RegExp, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
394-
pre<T = M>(method: 'insertMany' | RegExp, options: SchemaPreOptions, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
393+
pre<T = TModelType>(method: 'insertMany' | RegExp, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
394+
pre<T = TModelType>(method: 'insertMany' | RegExp, options: SchemaPreOptions, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
395395

396396
/** Object of currently defined query helpers on this schema. */
397397
query: TQueryHelpers;
@@ -413,11 +413,12 @@ declare module 'mongoose' {
413413

414414
/** Adds static "class" methods to Models compiled from this schema. */
415415
static<K extends keyof TStaticMethods>(name: K, fn: TStaticMethods[K]): this;
416-
static(obj: { [F in keyof TStaticMethods]: TStaticMethods[F] } & { [name: string]: (this: M, ...args: any[]) => any }): this;
417-
static(name: string, fn: (this: M, ...args: any[]) => any): this;
416+
static(obj: { [F in keyof TStaticMethods]: TStaticMethods[F] } & { [name: string]: (this: TModelType, ...args: any[]) => any }): this;
417+
static(name: string, fn: (this: TModelType, ...args: any[]) => any): this;
418418

419419
/** Object of currently defined statics on this schema. */
420-
statics: { [F in keyof TStaticMethods]: TStaticMethods[F] } & { [name: string]: (this: M, ...args: any[]) => any };
420+
statics: { [F in keyof TStaticMethods]: TStaticMethods[F] } &
421+
{ [name: string]: (this: TModelType, ...args: any[]) => unknown };
421422

422423
/** Creates a virtual type with the given name. */
423424
virtual<T = HydratedDocument<DocType, TVirtuals & TInstanceMethods, TQueryHelpers>>(

types/models.d.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -336,46 +336,47 @@ declare module 'mongoose' {
336336
insertMany<DocContents = TRawDocType>(
337337
docs: Array<DocContents | TRawDocType>,
338338
options: InsertManyOptions & { lean: true; }
339-
): Promise<Array<MergeType<MergeType<TRawDocType, DocContents>, Require_id<TRawDocType>>>>;
339+
): Promise<Array<Require_id<DocContents>>>;
340340
insertMany<DocContents = TRawDocType>(
341-
doc: DocContents,
341+
docs: DocContents | TRawDocType,
342+
options: InsertManyOptions & { lean: true; }
343+
): Promise<Array<Require_id<DocContents>>>;
344+
insertMany<DocContents = TRawDocType>(
345+
doc: DocContents | TRawDocType,
342346
options: InsertManyOptions & { ordered: false; rawResult: true; }
343-
): Promise<mongodb.InsertManyResult<TRawDocType> & {
347+
): Promise<mongodb.InsertManyResult<Require_id<DocContents>> & {
344348
mongoose: {
345349
validationErrors: Error[];
346350
results: Array<
347351
Error |
348352
Object |
349-
HydratedDocument<
350-
MergeType<
351-
MergeType<TRawDocType, DocContents>,
352-
Require_id<TRawDocType>
353-
>
354-
>
353+
MergeType<THydratedDocumentType, DocContents>
355354
>
356355
}
357356
}>;
358357
insertMany<DocContents = TRawDocType>(
359358
docs: Array<DocContents | TRawDocType>,
360359
options: InsertManyOptions & { rawResult: true; }
361-
): Promise<mongodb.InsertManyResult<TRawDocType>>;
360+
): Promise<mongodb.InsertManyResult<Require_id<DocContents>>>;
362361
insertMany<DocContents = TRawDocType>(
363362
docs: Array<DocContents | TRawDocType>
364-
): Promise<Array<HydratedDocument<MergeType<MergeType<TRawDocType, DocContents>, Require_id<TRawDocType>>, TVirtuals & TInstanceMethods, TQueryHelpers>>>;
363+
): Promise<Array<MergeType<THydratedDocumentType, Omit<DocContents, '_id'>>>>;
365364
insertMany<DocContents = TRawDocType>(
366365
doc: DocContents,
367366
options: InsertManyOptions & { lean: true; }
368-
): Promise<Array<MergeType<MergeType<TRawDocType, DocContents>, Require_id<TRawDocType>>>>;
367+
): Promise<Array<Require_id<DocContents>>>;
369368
insertMany<DocContents = TRawDocType>(
370369
doc: DocContents,
371370
options: InsertManyOptions & { rawResult: true; }
372-
): Promise<mongodb.InsertManyResult<TRawDocType>>;
371+
): Promise<mongodb.InsertManyResult<Require_id<DocContents>>>;
373372
insertMany<DocContents = TRawDocType>(
374373
doc: DocContents,
375374
options: InsertManyOptions
376-
): Promise<Array<HydratedDocument<MergeType<MergeType<TRawDocType, DocContents>, Require_id<TRawDocType>>, TVirtuals & TInstanceMethods, TQueryHelpers>>>;
377-
insertMany<DocContents = TRawDocType>(doc: DocContents): Promise<
378-
Array<HydratedDocument<MergeType<MergeType<TRawDocType, DocContents>, Require_id<TRawDocType>>, TVirtuals & TInstanceMethods, TQueryHelpers>>
375+
): Promise<Array<MergeType<THydratedDocumentType, Omit<DocContents, '_id'>>>>;
376+
insertMany<DocContents = TRawDocType>(
377+
doc: DocContents
378+
): Promise<
379+
Array<MergeType<THydratedDocumentType, Omit<DocContents, '_id'>>>
379380
>;
380381

381382
/** The name of the model */

types/schemaoptions.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ declare module 'mongoose' {
204204
* Model Statics methods.
205205
*/
206206
statics?: IfEquals<
207-
TStaticMethods,
208-
{},
209-
Record<any, (this: Model<DocType>, ...args: any) => unknown>,
210-
TStaticMethods
207+
TStaticMethods,
208+
{},
209+
{ [name: string]: (this: Model<DocType>, ...args: any[]) => unknown },
210+
{ [F in keyof TStaticMethods]: TStaticMethods[F] }
211211
>
212212

213213
/**

0 commit comments

Comments
 (0)