-
Type: Task
-
Resolution: Unresolved
-
Priority: Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
NODE-4470 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.