Skip to content

Commit

Permalink
Merge pull request #14720 from Automattic/vkarpov15/gh-14696
Browse files Browse the repository at this point in the history
types: correct `this` for `validate.validator` schematype option
  • Loading branch information
vkarpov15 authored Jul 4, 2024
2 parents a341dbc + 0a43d21 commit 54561d0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 15 deletions.
46 changes: 45 additions & 1 deletion test/types/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
SchemaType,
Types,
Query,
model
model,
ValidateOpts
} from 'mongoose';
import { expectType, expectError, expectAssignable } from 'tsd';
import { ObtainDocumentPathType, ResolvePathType } from '../../types/inferschematype';
Expand Down Expand Up @@ -1511,3 +1512,46 @@ function gh13772() {
const doc = new TestModel();
expectAssignable<RawDocType>(doc.toObject());
}

function gh14696() {
interface User {
name: string;
isActive: boolean;
isActiveAsync: boolean;
}

const x: ValidateOpts<unknown, User> = {
validator(v: any) {
expectAssignable<User>(this);
return !v || this.name === 'super admin';
}
};

const userSchema = new Schema<User>({
name: {
type: String,
required: [true, 'Name on card is required']
},
isActive: {
type: Boolean,
default: false,
validate: {
validator(v: any) {
expectAssignable<User>(this);
return !v || this.name === 'super admin';
}
}
},
isActiveAsync: {
type: Boolean,
default: false,
validate: {
async validator(v: any) {
expectAssignable<User>(this);
return !v || this.name === 'super admin';
}
}
}
});

}
2 changes: 1 addition & 1 deletion types/schematypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ declare module 'mongoose' {
alias?: string | string[];

/** Function or object describing how to validate this schematype. See [validation docs](https://mongoosejs.com/docs/validation.html). */
validate?: SchemaValidator<T> | AnyArray<SchemaValidator<T>>;
validate?: SchemaValidator<T, EnforcedDocType> | AnyArray<SchemaValidator<T, EnforcedDocType>>;

/** Allows overriding casting logic for this individual path. If a string, the given string overwrites Mongoose's default cast error message. */
cast?: string |
Expand Down
21 changes: 8 additions & 13 deletions types/validation.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
declare module 'mongoose' {

type SchemaValidator<T> = RegExp | [RegExp, string] | Function | [Function, string] | ValidateOpts<T> | ValidateOpts<T>[];
type SchemaValidator<T, EnforcedDocType> = RegExp | [RegExp, string] | Function | [Function, string] | ValidateOpts<T, EnforcedDocType> | ValidateOpts<T, EnforcedDocType>[];

interface ValidatorProps {
path: string;
Expand All @@ -13,23 +13,18 @@ declare module 'mongoose' {
(props: ValidatorProps): string;
}

interface ValidateFn<T> {
(value: T, props?: ValidatorProps & Record<string, any>): boolean;
}

interface LegacyAsyncValidateFn<T> {
(value: T, done: (result: boolean) => void): void;
}
type ValidateFn<T, EnforcedDocType> =
(this: EnforcedDocType, value: any, props?: ValidatorProps & Record<string, any>) => boolean;

interface AsyncValidateFn<T> {
(value: T, props?: ValidatorProps & Record<string, any>): Promise<boolean>;
}
type AsyncValidateFn<T, EnforcedDocType> =
(this: EnforcedDocType, value: any, props?: ValidatorProps & Record<string, any>) => Promise<boolean>;

interface ValidateOpts<T> {
interface ValidateOpts<T, EnforcedDocType> {
msg?: string;
message?: string | ValidatorMessageFn;
type?: string;
validator: ValidateFn<T> | LegacyAsyncValidateFn<T> | AsyncValidateFn<T>;
validator: ValidateFn<T, EnforcedDocType>
| AsyncValidateFn<T, EnforcedDocType>;
propsParameter?: boolean;
}
}

0 comments on commit 54561d0

Please sign in to comment.