diff --git a/test/types/schema.test.ts b/test/types/schema.test.ts index 8a0dd423801..e5eb5e155f0 100644 --- a/test/types/schema.test.ts +++ b/test/types/schema.test.ts @@ -702,3 +702,38 @@ function gh12030() { }>({} as InferSchemaType); } + +function pluginOptions() { + interface SomePluginOptions { + option1?: string; + option2: number; + } + + function pluginFunction(schema: Schema, options: SomePluginOptions) { + return; // empty function, to satisfy lint option + } + + const schema = new Schema({}); + expectType>(schema.plugin(pluginFunction)); // test that chaining would be possible + + // could not add strict tests that the parameters are inferred correctly, because i dont know how this would be done in tsd + + // test basic inferrence + expectError(schema.plugin(pluginFunction, {})); // should error because "option2" is not optional + schema.plugin(pluginFunction, { option2: 0 }); + schema.plugin(pluginFunction, { option1: 'string', option2: 1 }); + expectError(schema.plugin(pluginFunction, { option1: 'string' })); // should error because "option2" is not optional + expectError(schema.plugin(pluginFunction, { option2: 'string' })); // should error because "option2" type is "number" + expectError(schema.plugin(pluginFunction, { option1: 0 })); // should error because "option1" type is "string" + + // test plugins without options defined + function pluginFunction2(schema: Schema) { + return; // empty function, to satisfy lint option + } + schema.plugin(pluginFunction2); + expectError(schema.plugin(pluginFunction2, {})); // should error because no options argument is defined + + // test overwriting options + schema.plugin(pluginFunction2, { option2: 0 }); + expectError(schema.plugin(pluginFunction2, {})); // should error because "option2" is not optional +} diff --git a/types/index.d.ts b/types/index.d.ts index 084b69296fc..c00915591d8 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -157,6 +157,8 @@ declare module 'mongoose' { type QueryResultType = T extends Query ? ResultType : never; + type PluginFunction = (schema: Schema, opts?: any) => void; + export class Schema, TInstanceMethods = {}, TQueryHelpers = {}, TVirtuals = {}, TStaticMethods = {}, TPathTypeKey extends TypeKeyBaseType = DefaultTypeKey, @@ -239,7 +241,7 @@ declare module 'mongoose' { pathType(path: string): string; /** Registers a plugin for this schema. */ - plugin(fn: (schema: Schema, opts?: any) => void, opts?: any): this; + plugin, POptions extends Parameters[1] = Parameters[1]>(fn: PFunc, opts?: POptions): this; /** Defines a post hook for the model. */ post>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PostMiddlewareFunction): this;