Skip to content

Commit

Permalink
Merge pull request #13851 from pshaddel/master
Browse files Browse the repository at this point in the history
fix: Pass correct document type to required and default function
  • Loading branch information
vkarpov15 committed Sep 12, 2023
2 parents c27500b + 64cec02 commit 71bbf64
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 20 deletions.
12 changes: 12 additions & 0 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1218,3 +1218,15 @@ function gh13800() {
expectError<string>(this.someOtherField);
});
}

async function gh13797() {
interface IUser {
name: string;
}
new Schema<IUser>({ name: { type: String, required: function() {
expectType<IUser>(this); return true;
} } });
new Schema<IUser>({ name: { type: String, default: function() {
expectType<IUser>(this); return '';
} } });
}
22 changes: 11 additions & 11 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ declare module 'mongoose' {
/**
* Create a new schema
*/
constructor(definition?: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | DocType, options?: SchemaOptions<DocType, TInstanceMethods, TQueryHelpers, TStaticMethods, TVirtuals, THydratedDocumentType> | ResolveSchemaOptions<TSchemaOptions>);
constructor(definition?: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>, EnforcedDocType> | DocType, options?: SchemaOptions<DocType, TInstanceMethods, TQueryHelpers, TStaticMethods, TVirtuals, THydratedDocumentType> | ResolveSchemaOptions<TSchemaOptions>);

/** Adds key path / schema type pairs to this schema. */
add(obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>> | Schema, prefix?: string): this;
Expand Down Expand Up @@ -300,7 +300,7 @@ declare module 'mongoose' {
methods: { [F in keyof TInstanceMethods]: TInstanceMethods[F] } & AnyObject;

/** The original object passed to the schema constructor */
obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>>;
obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>, EnforcedDocType>;

/** Gets/sets schema paths. */
path<ResultType extends SchemaType = SchemaType<any, THydratedDocumentType>>(path: string): ResultType;
Expand Down Expand Up @@ -484,26 +484,26 @@ declare module 'mongoose' {
? DateSchemaDefinition
: (Function | string);

export type SchemaDefinitionProperty<T = undefined> = SchemaDefinitionWithBuiltInClass<T> |
SchemaTypeOptions<T extends undefined ? any : T> |
export type SchemaDefinitionProperty<T = undefined, EnforcedDocType = any> = SchemaDefinitionWithBuiltInClass<T> |
SchemaTypeOptions<T extends undefined ? any : T, EnforcedDocType> |
typeof SchemaType |
Schema<any, any, any> |
Schema<any, any, any>[] |
SchemaTypeOptions<T extends undefined ? any : Unpacked<T>>[] |
SchemaTypeOptions<T extends undefined ? any : Unpacked<T>, EnforcedDocType>[] |
Function[] |
SchemaDefinition<T> |
SchemaDefinition<Unpacked<T>>[] |
SchemaDefinition<T, EnforcedDocType> |
SchemaDefinition<Unpacked<T>, EnforcedDocType>[] |
typeof Schema.Types.Mixed |
MixedSchemaTypeOptions;
MixedSchemaTypeOptions<EnforcedDocType>;

export type SchemaDefinition<T = undefined> = T extends undefined
export type SchemaDefinition<T = undefined, EnforcedDocType = any> = T extends undefined
? { [path: string]: SchemaDefinitionProperty; }
: { [path in keyof T]?: SchemaDefinitionProperty<T[path]>; };
: { [path in keyof T]?: SchemaDefinitionProperty<T[path], EnforcedDocType>; };

export type AnyArray<T> = T[] | ReadonlyArray<T>;
export type ExtractMongooseArray<T> = T extends Types.Array<any> ? AnyArray<Unpacked<T>> : T;

export interface MixedSchemaTypeOptions extends SchemaTypeOptions<Schema.Types.Mixed> {
export interface MixedSchemaTypeOptions<EnforcedDocType> extends SchemaTypeOptions<Schema.Types.Mixed, EnforcedDocType> {
type: typeof Schema.Types.Mixed;
}

Expand Down
18 changes: 9 additions & 9 deletions types/schematypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ declare module 'mongoose' {

type DefaultType<T> = T extends Schema.Types.Mixed ? any : Partial<ExtractMongooseArray<T>>;

class SchemaTypeOptions<T> {
class SchemaTypeOptions<T, EnforcedDocType = any> {
type?:
T extends string ? StringSchemaDefinition :
T extends number ? NumberSchemaDefinition :
Expand All @@ -48,12 +48,12 @@ declare module 'mongoose' {
T extends Map<any, any> ? SchemaDefinition<typeof Map> :
T extends Buffer ? SchemaDefinition<typeof Buffer> :
T extends Types.ObjectId ? ObjectIdSchemaDefinition :
T extends Types.ObjectId[] ? AnyArray<ObjectIdSchemaDefinition> | AnyArray<SchemaTypeOptions<ObjectId>> :
T extends object[] ? (AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<T>>> | AnyArray<SchemaTypeOptions<Unpacked<T>>>) :
T extends string[] ? AnyArray<StringSchemaDefinition> | AnyArray<SchemaTypeOptions<string>> :
T extends number[] ? AnyArray<NumberSchemaDefinition> | AnyArray<SchemaTypeOptions<number>> :
T extends boolean[] ? AnyArray<BooleanSchemaDefinition> | AnyArray<SchemaTypeOptions<boolean>> :
T extends Function[] ? AnyArray<Function | string> | AnyArray<SchemaTypeOptions<Unpacked<T>>> :
T extends Types.ObjectId[] ? AnyArray<ObjectIdSchemaDefinition> | AnyArray<SchemaTypeOptions<ObjectId, EnforcedDocType>> :
T extends object[] ? (AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<T>>> | AnyArray<SchemaTypeOptions<Unpacked<T>, EnforcedDocType>>) :
T extends string[] ? AnyArray<StringSchemaDefinition> | AnyArray<SchemaTypeOptions<string, EnforcedDocType>> :
T extends number[] ? AnyArray<NumberSchemaDefinition> | AnyArray<SchemaTypeOptions<number, EnforcedDocType>> :
T extends boolean[] ? AnyArray<BooleanSchemaDefinition> | AnyArray<SchemaTypeOptions<boolean, EnforcedDocType>> :
T extends Function[] ? AnyArray<Function | string> | AnyArray<SchemaTypeOptions<Unpacked<T>, EnforcedDocType>> :
T | typeof SchemaType | Schema<any, any, any> | SchemaDefinition<T> | Function | AnyArray<Function>;

/** Defines a virtual with the given name that gets/sets this path. */
Expand All @@ -74,13 +74,13 @@ declare module 'mongoose' {
* path cannot be set to a nullish value. If a function, Mongoose calls the
* function and only checks for nullish values if the function returns a truthy value.
*/
required?: boolean | (() => boolean) | [boolean, string] | [() => boolean, string];
required?: boolean | ((this: EnforcedDocType) => boolean) | [boolean, string] | [(this: EnforcedDocType) => boolean, string];

/**
* The default value for this path. If a function, Mongoose executes the function
* and uses the return value as the default.
*/
default?: DefaultType<T> | ((this: any, doc: any) => DefaultType<T>) | null;
default?: DefaultType<T> | ((this: EnforcedDocType, doc: any) => DefaultType<T>) | null;

/**
* The model that `populate()` should use if populating this path.
Expand Down

0 comments on commit 71bbf64

Please sign in to comment.