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

fix(NODE-3454): projection types are too narrow #2924

Merged
merged 9 commits into from Aug 4, 2021

Conversation

nbbeeken
Copy link
Contributor

With the introduction of aggregation operations in 4.4 in projection documents typing projections is very complex. I propose here we remove projection type constrains altogether to permit the many operators permitted by the server.

@dariakp dariakp added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Aug 2, 2021
@dariakp dariakp self-assigned this Aug 2, 2021
Copy link
Contributor

@dariakp dariakp left a comment

Choose a reason for hiding this comment

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

It looks like there are two unused vars failing the build:

[2021/07/30 20:43:13.893] /data/mci/935b7979091d2b96139cddbecd5ed5ae/src/src/mongo_types.ts
[2021/07/30 20:43:13.893] 173:24 warning 'TSchema' is defined but never used @typescript-eslint/no-unused-vars
[2021/07/30 20:43:13.893] /data/mci/935b7979091d2b96139cddbecd5ed5ae/src/src/operations/find.ts
[2021/07/30 20:43:13.893] 21:30 warning 'TSchema' is defined but never used @typescript-eslint/no-unused-vars

.find({ _id: { $in: [] } })
.sort({ _id: -1 })
.limit(3)
.project<PublicMeme>(publicMemeProjection) // <== location of TS2345 error
Copy link
Contributor

Choose a reason for hiding this comment

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

what's TS2345?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy pasta-ed from the ticket its the type error that was occuring with the projection constraints, I put in the actual message for clarity.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think including the ticket number would make sense, to provide context in the future about which TS2345 error this is referring to.

@@ -74,13 +74,13 @@ expectNotType<{ age: number }[]>(await typedCollection.find().project({ name: 1
expectType<{ notExistingField: unknown }[]>(
await typedCollection.find().project({ notExistingField: 1 }).toArray()
);
expectNotType<TypedDoc[]>(await typedCollection.find().project({ notExistingField: 1 }).toArray());
expectType<TypedDoc[]>(await typedCollection.find().project({ notExistingField: 1 }).toArray());
Copy link
Contributor

Choose a reason for hiding this comment

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

I thought this was supposed to yield Document[], which shouldn't match TypedDoc[]?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected the test, I think this is correct, unless we want to change the return to always be generic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is part of the larger issue that we discovered, we'll tackle it in NODE-3468

likes: number;
someRandomProp: boolean; // Projection makes no enforcement on anything
// the convenience parameter project<X>() allows you to define a return type,
// otherwise projections returns a generic Document
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a test to show an expectType<Document[]> here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added!

/** Sets the limit of documents returned in the query. */
limit?: number;
/** Set to sort the documents coming back from the query. Array of indexes, `[['a', 1]]` etc. */
sort?: Sort;
/** The fields to return in the query. Object of fields to either include or exclude (one of, not both), `{'a':1, 'b': 1}` **or** `{'a': 0, 'b': 0}` */
projection?: Projection<TSchema>;
projection?: Document;
Copy link
Contributor

@PaulEndri PaulEndri Aug 3, 2021

Choose a reason for hiding this comment

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

Wouldn't setting this to TSchema make the default functionality the same but still allow a more granular level of control without breaking things? And remove the need for the eslint disable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean setting projection?: TSchema? I think that would cause issue with the typical projection of inclusion / exclusion like { _id: 0, name: 1 }. where name: string in the TSchema

@nbbeeken nbbeeken requested a review from dariakp August 4, 2021 17:58
@dariakp dariakp added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels Aug 4, 2021
@dariakp dariakp requested review from emadum and durran August 4, 2021 18:23
/**
* @public
* Projection is flexible to permit the wide array of aggregation operators
* @deprecated since v4.1.0: Since projections support all of aggregation operations we have no plans to narrow this type further
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* @deprecated since v4.1.0: Since projections support all of aggregation operations we have no plans to narrow this type further
* @deprecated since v4.1.0: Since projections support all aggregation operations we have no plans to narrow this type further

Partial<Record<string, ProjectionOperators | 0 | 1 | boolean>>;
/**
* @public
* @deprecated since v4.1.0: Since projections support all of aggregation operations we have no plans to narrow this type further
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* @deprecated since v4.1.0: Since projections support all of aggregation operations we have no plans to narrow this type further
* @deprecated since v4.1.0: Since projections support all aggregation operations we have no plans to narrow this type further

.find({ _id: { $in: [] } })
.sort({ _id: -1 })
.limit(3)
.project<PublicMeme>(publicMemeProjection) // <== location of TS2345 error
Copy link
Contributor

Choose a reason for hiding this comment

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

I think including the ticket number would make sense, to provide context in the future about which TS2345 error this is referring to.

Copy link
Contributor

@emadum emadum left a comment

Choose a reason for hiding this comment

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

Few small requests but otherwise LGTM 👍

@nbbeeken nbbeeken requested a review from emadum August 4, 2021 18:51
@dariakp dariakp merged commit 48d6da9 into 4.1 Aug 4, 2021
@dariakp dariakp deleted the NODE-3454/projection-types branch August 4, 2021 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team Review Needs review from team
Projects
None yet
4 participants