Skip to content

Commit 54561d0

Browse files
authored
Merge pull request #14720 from Automattic/vkarpov15/gh-14696
types: correct `this` for `validate.validator` schematype option
2 parents a341dbc + 0a43d21 commit 54561d0

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

test/types/schema.test.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
SchemaType,
1919
Types,
2020
Query,
21-
model
21+
model,
22+
ValidateOpts
2223
} from 'mongoose';
2324
import { expectType, expectError, expectAssignable } from 'tsd';
2425
import { ObtainDocumentPathType, ResolvePathType } from '../../types/inferschematype';
@@ -1511,3 +1512,46 @@ function gh13772() {
15111512
const doc = new TestModel();
15121513
expectAssignable<RawDocType>(doc.toObject());
15131514
}
1515+
1516+
function gh14696() {
1517+
interface User {
1518+
name: string;
1519+
isActive: boolean;
1520+
isActiveAsync: boolean;
1521+
}
1522+
1523+
const x: ValidateOpts<unknown, User> = {
1524+
validator(v: any) {
1525+
expectAssignable<User>(this);
1526+
return !v || this.name === 'super admin';
1527+
}
1528+
};
1529+
1530+
const userSchema = new Schema<User>({
1531+
name: {
1532+
type: String,
1533+
required: [true, 'Name on card is required']
1534+
},
1535+
isActive: {
1536+
type: Boolean,
1537+
default: false,
1538+
validate: {
1539+
validator(v: any) {
1540+
expectAssignable<User>(this);
1541+
return !v || this.name === 'super admin';
1542+
}
1543+
}
1544+
},
1545+
isActiveAsync: {
1546+
type: Boolean,
1547+
default: false,
1548+
validate: {
1549+
async validator(v: any) {
1550+
expectAssignable<User>(this);
1551+
return !v || this.name === 'super admin';
1552+
}
1553+
}
1554+
}
1555+
});
1556+
1557+
}

types/schematypes.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ declare module 'mongoose' {
6060
alias?: string | string[];
6161

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

6565
/** Allows overriding casting logic for this individual path. If a string, the given string overwrites Mongoose's default cast error message. */
6666
cast?: string |

types/validation.d.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
declare module 'mongoose' {
22

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

55
interface ValidatorProps {
66
path: string;
@@ -13,23 +13,18 @@ declare module 'mongoose' {
1313
(props: ValidatorProps): string;
1414
}
1515

16-
interface ValidateFn<T> {
17-
(value: T, props?: ValidatorProps & Record<string, any>): boolean;
18-
}
19-
20-
interface LegacyAsyncValidateFn<T> {
21-
(value: T, done: (result: boolean) => void): void;
22-
}
16+
type ValidateFn<T, EnforcedDocType> =
17+
(this: EnforcedDocType, value: any, props?: ValidatorProps & Record<string, any>) => boolean;
2318

24-
interface AsyncValidateFn<T> {
25-
(value: T, props?: ValidatorProps & Record<string, any>): Promise<boolean>;
26-
}
19+
type AsyncValidateFn<T, EnforcedDocType> =
20+
(this: EnforcedDocType, value: any, props?: ValidatorProps & Record<string, any>) => Promise<boolean>;
2721

28-
interface ValidateOpts<T> {
22+
interface ValidateOpts<T, EnforcedDocType> {
2923
msg?: string;
3024
message?: string | ValidatorMessageFn;
3125
type?: string;
32-
validator: ValidateFn<T> | LegacyAsyncValidateFn<T> | AsyncValidateFn<T>;
26+
validator: ValidateFn<T, EnforcedDocType>
27+
| AsyncValidateFn<T, EnforcedDocType>;
3328
propsParameter?: boolean;
3429
}
3530
}

0 commit comments

Comments
 (0)