Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types: enhanced Document's methods #13739

Merged
merged 2 commits into from Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 32 additions & 0 deletions test/types/document.test.ts
Expand Up @@ -312,3 +312,35 @@ function gh13094() {
const doc3: UserDocumentAny = null as any;
expectType<string>(doc3.name); */
}

function gh13738() {
interface IPerson {
age: number;
dob: Date;
settings: {
theme: string;
alerts: {
sms: boolean;
}
}
}

const schema = new Schema<IPerson>({
age: Number,
dob: Date,
settings: {
theme: String,
alerts: {
sms: Boolean
}
}
});

const Person = model<IPerson>('Person', schema);

const person = new Person({ name: 'person', dob: new Date(), settings: { alerts: { sms: true }, theme: 'light' } });

expectType<number>(person.get('age'));
expectType<Date>(person.get('dob'));
expectType<{ theme: string; alerts: { sms: boolean } }>(person.get('settings'));
}
12 changes: 12 additions & 0 deletions types/document.d.ts
Expand Up @@ -135,6 +135,7 @@ declare module 'mongoose' {
errors?: Error.ValidationError;

/** Returns the value of a path. */
get<T extends keyof DocType>(path: T, type?: any, options?: any): DocType[T];
get(path: string, type?: any, options?: any): any;

/**
Expand All @@ -157,30 +158,37 @@ declare module 'mongoose' {
init(obj: AnyObject, opts?: AnyObject): this;

/** Marks a path as invalid, causing validation to fail. */
invalidate<T extends keyof DocType>(path: T, errorMsg: string | NativeError, value?: any, kind?: string): NativeError | null;
invalidate(path: string, errorMsg: string | NativeError, value?: any, kind?: string): NativeError | null;

/** Returns true if `path` was directly set and modified, else false. */
isDirectModified<T extends keyof DocType>(path: T | Array<T>): boolean;
isDirectModified(path: string | Array<string>): boolean;

/** Checks if `path` was explicitly selected. If no projection, always returns true. */
isDirectSelected<T extends keyof DocType>(path: T): boolean;
isDirectSelected(path: string): boolean;

/** Checks if `path` is in the `init` state, that is, it was set by `Document#init()` and not modified since. */
isInit<T extends keyof DocType>(path: T): boolean;
isInit(path: string): boolean;

/**
* Returns true if any of the given paths are modified, else false. If no arguments, returns `true` if any path
* in this document is modified.
*/
isModified<T extends keyof DocType>(path?: T | Array<T>): boolean;
isModified(path?: string | Array<string>): boolean;

/** Boolean flag specifying if the document is new. */
isNew: boolean;

/** Checks if `path` was selected in the source query which initialized this document. */
isSelected<T extends keyof DocType>(path: T): boolean;
isSelected(path: string): boolean;

/** Marks the path as having pending changes to write to the db. */
markModified<T extends keyof DocType>(path: T, scope?: any): void;
markModified(path: string, scope?: any): void;

/** Returns the list of paths that have been modified. */
Expand Down Expand Up @@ -216,6 +224,7 @@ declare module 'mongoose' {
schema: Schema;

/** Sets the value of a path, or many paths. */
set<T extends keyof DocType>(path: T, val: DocType[T], type: any, options?: DocumentSetOptions): this;
set(path: string | Record<string, any>, val: any, type: any, options?: DocumentSetOptions): this;
set(path: string | Record<string, any>, val: any, options?: DocumentSetOptions): this;
set(value: string | Record<string, any>): this;
Expand All @@ -228,17 +237,20 @@ declare module 'mongoose' {
toObject<T = Require_id<DocType>>(options?: ToObjectOptions): Require_id<T>;

/** Clears the modified state on the specified path. */
unmarkModified<T extends keyof DocType>(path: T): void;
unmarkModified(path: string): void;

/** Sends an updateOne command with this document `_id` as the query selector. */
updateOne(update?: UpdateQuery<this> | UpdateWithAggregationPipeline, options?: QueryOptions | null): Query<any, this>;

/** Executes registered validation rules for this document. */
validate<T extends keyof DocType>(pathsToValidate?: T | T[], options?: AnyObject): Promise<void>;
validate(pathsToValidate?: pathsToValidate, options?: AnyObject): Promise<void>;
validate(options: { pathsToSkip?: pathsToSkip }): Promise<void>;

/** Executes registered validation rules (skipping asynchronous validators) for this document. */
validateSync(options: { pathsToSkip?: pathsToSkip, [k: string]: any }): Error.ValidationError | null;
validateSync<T extends keyof DocType>(pathsToValidate?: T | T[], options?: AnyObject): Error.ValidationError | null;
validateSync(pathsToValidate?: pathsToValidate, options?: AnyObject): Error.ValidationError | null;
}
}