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

Conversation

maybesmurf
Copy link
Contributor

ref: #13738

Summary
Improved various Document's methods

Copy link
Collaborator

@vkarpov15 vkarpov15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has some neat ideas, but also has several issues that prevent us from merging. Overall suggestions:

  1. Get rid of FlatPath<> entirely. Make the T extends FlatPath<DocType> generics into T extends keyof DocType. That will mean we at least have some of the syntactic benefits for top-level paths.
  2. Bring back fallback syntaxes for passing in arbitrary strings.

@@ -40,4 +40,34 @@ type IfEquals<T, U, Y = true, N = false> =
(<G>() => G extends T ? 1 : 0) extends
(<G>() => G extends U ? 1 : 0) ? Y : N;

type IsAny<T> = unknown extends T ? ([keyof T] extends [never] ? false : true) : false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have IfAny<>, so this is unnecessary

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(pathsToValidate?: pathsToValidate, options?: AnyObject): Error.ValidationError | null;
validateSync<T extends FlatPath<DocType>>(pathsToValidate?: T | T[], options?: AnyObject): Error.ValidationError | null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit wary of using FlatPath<> by default because of potential infinite recursion issues. Any self-referencing objects will lead to FlatPath<> blowing up, which is one of the reasons why the MongoDB Node driver no longer uses their Join helper by default.

@@ -207,7 +209,7 @@ declare module 'mongoose' {
populated(path: string): any;

/** Sends a replaceOne command with this document `_id` as the query selector. */
replaceOne(replacement?: AnyObject, options?: QueryOptions | null): Query<any, this>;
replaceOne(replacement?: Partial<Omit<DocType, '_id'>>, options?: QueryOptions | null): Query<any, this>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect. 1) AnyObject is more correct, because Mongoose will run casting to handle any types that don't match, 2) Partial<> is incorrect because required fields are still required, 3) omitting _id is incorrect: you can specify _id as long as the replacement has the same _id as the document, but there's no way to know whether the _id is the same at compile time.

@@ -191,7 +193,7 @@ declare module 'mongoose' {
* for immutable properties. Behaves similarly to `set()`, except for it
* unsets all properties that aren't in `obj`.
*/
overwrite(obj: AnyObject): this;
overwrite(obj: Partial<Omit<DocType, '_id'>>): this;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here. AnyObject is more correct, Partial<> is wrong, and omitting _id is wrong.


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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This syntax is nice, but would be good to keep the isDirectSelected(path: string): boolean; syntax as a fallback because it is perfectly valid to call isDirectSelected() on a field that's not in the schema.

@maybesmurf
Copy link
Contributor Author

maybesmurf commented Aug 15, 2023

You have some good points. Changes made as instructed. Please review. Thanks

Copy link
Collaborator

@vkarpov15 vkarpov15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks 👍

@vkarpov15 vkarpov15 merged commit 244a543 into Automattic:master Aug 22, 2023
3 checks passed
@vkarpov15 vkarpov15 added this to the 7.4.4 milestone Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants