Details
-
Improvement
-
Status: Blocked
-
Unknown
-
Resolution: Unresolved
-
None
-
None
Description
When creating a new document using insertOne(), most users prefer for MongoDB to automatically assign a unique document _id. For example, if my document looks like this...
// Life before PR 3077
|
interface Book {
|
_id: ObjectId;
|
title: string
|
}
|
...then I might call insertOne({title: 'My Book'}), omitting the _id field, which was optional in this context.
However, a minority of users sometimes want to specify this _id explicitly. To help that minority of users some of the time, PR node-mongodb-native#3077 introduced a safeguard for enforcing that the _id must always be specified when calling insertOne().
Unfortunately, this new safeguard is controlled by the Book._id declaration: To get the behavior that most users want, we must now change our interface declaration to be like this:
// Life after PR 3077
|
interface Book {
|
// This must be optional, otherwise insertOne() will require the _id
|
_id?: ObjectId;
|
title: string
|
}
|
This is unfortunate:
1. This optional Book._id field does not accurately represents the real document: Every MongoDB document always has an _id. (Note that the input to insertOne() is NOT a document, it is a partial input used to initialize a new document.)
2. Everywhere that we previously wrote Book, now we must write WithId\<Book\>. Otherwise I cannot read the _id field without adding annoying tests/casts for the impossible undefined state. This effect cascades across every document in our entire code base. Another developer voiced the same concern in 3077#issuecomment
I understand that PR 3077 was a nice improvement for a minority of users sometimes. But is there a way to accomplish that goal without making things worse for everyone else?
Technical details
In the new implementation, this policy is controlled by this declaration:
export declare type OptionalUnlessRequiredId<TSchema> = TSchema extends {
|
_id: any;
|
} ? TSchema : OptionalId<TSchema>;
|
Ideas for improvements
- Maybe instead of {{TSchema extends { _id: any; }}}, the we check for some kind of _id: RequiredOnInsert<TSchema>.
- Maybe Collection<T> could have a parameterization as Collection<T, IdRequiredOnInsert> or CollectionWithExplicitId<T>
- Just revert PR #3077 if it causes more problems than it solves
Maybe other people have better suggestions.
Attachments
Issue Links
- depends on
-
NODE-4471 Investigate NODE-4470 - Replace OptionalUnlessRequiredId with something less awkward
-
- Backlog
-
- is related to
-
NODE-4498 Test assignability of returned api results with OptionalId<Schema> to Schema with _id
-
- Closed
-
- related to
-
NODE-3904 Consider preferring safety of existing types over compatibility with future operators
-
- Backlog
-