Skip to content

Commit 67c2e93

Browse files
authored
Merge pull request #12196 from hasezoey/pluginOptions
fix(types): add schema plugin option inference
2 parents 53dc72b + 4e95e33 commit 67c2e93

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

test/types/schema.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,3 +702,38 @@ function gh12030() {
702702
}>({} as InferSchemaType<typeof Schema6>);
703703

704704
}
705+
706+
function pluginOptions() {
707+
interface SomePluginOptions {
708+
option1?: string;
709+
option2: number;
710+
}
711+
712+
function pluginFunction(schema: Schema<any>, options: SomePluginOptions) {
713+
return; // empty function, to satisfy lint option
714+
}
715+
716+
const schema = new Schema({});
717+
expectType<Schema<any>>(schema.plugin(pluginFunction)); // test that chaining would be possible
718+
719+
// could not add strict tests that the parameters are inferred correctly, because i dont know how this would be done in tsd
720+
721+
// test basic inferrence
722+
expectError(schema.plugin(pluginFunction, {})); // should error because "option2" is not optional
723+
schema.plugin(pluginFunction, { option2: 0 });
724+
schema.plugin(pluginFunction, { option1: 'string', option2: 1 });
725+
expectError(schema.plugin(pluginFunction, { option1: 'string' })); // should error because "option2" is not optional
726+
expectError(schema.plugin(pluginFunction, { option2: 'string' })); // should error because "option2" type is "number"
727+
expectError(schema.plugin(pluginFunction, { option1: 0 })); // should error because "option1" type is "string"
728+
729+
// test plugins without options defined
730+
function pluginFunction2(schema: Schema<any>) {
731+
return; // empty function, to satisfy lint option
732+
}
733+
schema.plugin(pluginFunction2);
734+
expectError(schema.plugin(pluginFunction2, {})); // should error because no options argument is defined
735+
736+
// test overwriting options
737+
schema.plugin<any, SomePluginOptions>(pluginFunction2, { option2: 0 });
738+
expectError(schema.plugin<any, SomePluginOptions>(pluginFunction2, {})); // should error because "option2" is not optional
739+
}

types/index.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ declare module 'mongoose' {
157157

158158
type QueryResultType<T> = T extends Query<infer ResultType, any> ? ResultType : never;
159159

160+
type PluginFunction<DocType> = (schema: Schema<DocType>, opts?: any) => void;
161+
160162
export class Schema<EnforcedDocType = any, M = Model<EnforcedDocType, any, any, any>, TInstanceMethods = {}, TQueryHelpers = {}, TVirtuals = {},
161163
TStaticMethods = {},
162164
TPathTypeKey extends TypeKeyBaseType = DefaultTypeKey,
@@ -239,7 +241,7 @@ declare module 'mongoose' {
239241
pathType(path: string): string;
240242

241243
/** Registers a plugin for this schema. */
242-
plugin(fn: (schema: Schema<DocType>, opts?: any) => void, opts?: any): this;
244+
plugin<PFunc extends PluginFunction<DocType>, POptions extends Parameters<PFunc>[1] = Parameters<PFunc>[1]>(fn: PFunc, opts?: POptions): this;
243245

244246
/** Defines a post hook for the model. */
245247
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PostMiddlewareFunction<T, T>): this;

0 commit comments

Comments
 (0)