-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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-6029): update types for collection listing indexes #4072
fix(NODE-6029): update types for collection listing indexes #4072
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @prenaissance - thanks for the submission! I left some comments about the implementation.
src/operations/indexes.ts
Outdated
export type IndexDescriptionInfo = Omit<IndexDescription, 'key' | 'version'> & { | ||
key: { [key: string]: IndexDirection }; | ||
v?: IndexDescription['version']; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally try to keep our type definitions for server responses flexible so that if the server modifies a response in a future server version the driver is still compatible with it. Could we & Document
here? I think that will provide type safety on known keys but will allow unknown keys without a Typescript error.
src/collection.ts
Outdated
@@ -693,8 +701,13 @@ export class Collection<TSchema extends Document = Document> { | |||
* | |||
* @param options - Optional settings for the command | |||
*/ | |||
async indexInformation(options?: IndexInformationOptions): Promise<Document> { | |||
return await this.indexes({ ...options, full: options?.full ?? false }); | |||
async indexInformation<TFull extends boolean = false>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's preferrable to avoid computed types as the return types from our APIs, since they don't provided users with information about the return type of a function until a user 1) reads the source of the computed type or 2) writes code using the API and checks the computed return type. Could we accomplish the same here using overloads and removing all TFull
generics? Something like:
indexInformation(
options: IndexInformationOptions & { full: true }
): Promise<IndexDescriptionInfo[]>;
indexInformation(
options: IndexInformationOptions & { full: false }
): Promise<IndexDescriptionCompact>;
indexInformation(
options: IndexInformationOptions & { full: boolean }
): Promise<IndexDescriptionCompact | IndexDescriptionInfo[]>;
This has the additional benefits of
- better documentation, because our tooling will generate a doc entry for each overload
- clearly defined overloads with existing IDE tooling
- each overload can be documented originally (if desired).
for example - here's what VSCode could hypothetically display if we used overloads:
src/operations/indexes.ts
Outdated
@@ -72,7 +72,7 @@ export type IndexSpecification = OneOrMore< | |||
>; | |||
|
|||
/** @public */ | |||
export interface IndexInformationOptions extends ListIndexesOptions { | |||
export interface IndexInformationOptions<TFull extends boolean> extends ListIndexesOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could consider this a breaking change, since existing users' code that makes use of IndexInformationOptions
would break because they wouldn't be providing a generic argument. We could fix this by providing a default, but I think overloads are preferable (see my comment on Collection.indexInformation()
).
Thank you for the feedback. I fixed the comments and also added tests for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one last round of small comments, otherwise LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just updated the description from Document.prototype
call outs to Collection.prototype
Description
What is changing?
Update the return type of
Collection.prototype.indexes
andCollection.prototype.indexInformation
to an array of indexes with full properties when thefull
option is true and to a Record of <index name> - <keys and direction> when the full option is false.Is there new documentation needed for these changes?
No.
What is the motivation for this change?
The old types were incorrect in regards to the
full
option and were very wide. This will avoid making some type mistakes when using these methods.Release Highlight
Index information helpers have accurate Typescript return types
Collection.indexInformation()
,Collection.indexes()
andDb.indexInformation()
are helpers that return index information for a given collection or database. These helpers take an option,full
, that configures whether the return value contains full index descriptions or a compact summary:However, the Typescript return type of these helpers was always
Document
. Thanks to @prenaissance, these helpers now have accurate type information! The helpers return a new type,IndexDescriptionCompact | IndexDescriptionInfo[]
, which accurately reflects the return type of these helpers. The helpers also support type narrowing by providing a boolean literal as an option to the API:Double check the following
npm run check:lint
scripttype(NODE-xxxx)[!]: description
feat(NODE-1234)!: rewriting everything in coffeescript