Skip to content

Commit 307d623

Browse files
avalydariakp
andauthored
fix(NODE-3770): Filter type uses WithId on the schema (#3053)
Co-authored-by: Daria Pardue <[email protected]>
1 parent b6a63df commit 307d623

File tree

5 files changed

+17
-26
lines changed

5 files changed

+17
-26
lines changed

src/collection.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,9 @@ export class Collection<TSchema extends Document = Document> {
730730
* @param filter - The filter predicate. If unspecified, then all documents in the collection will match the predicate
731731
*/
732732
find(): FindCursor<WithId<TSchema>>;
733-
find(filter: Filter<WithId<TSchema>>, options?: FindOptions): FindCursor<WithId<TSchema>>;
734-
find<T>(filter: Filter<WithId<TSchema>>, options?: FindOptions): FindCursor<T>;
735-
find(filter?: Filter<WithId<TSchema>>, options?: FindOptions): FindCursor<WithId<TSchema>> {
733+
find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;
734+
find<T>(filter: Filter<TSchema>, options?: FindOptions): FindCursor<T>;
735+
find(filter?: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>> {
736736
if (arguments.length > 2) {
737737
throw new MongoInvalidArgumentError(
738738
'Method "collection.find()" accepts at most two arguments'

src/mongo_types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
5656

5757
/** A MongoDB filter can be some portion of the schema or a set of operators @public */
5858
export type Filter<TSchema> = {
59-
[P in keyof TSchema]?: Condition<TSchema[P]>;
60-
} & RootFilterOperators<TSchema>;
59+
[P in keyof WithId<TSchema>]?: Condition<WithId<TSchema>[P]>;
60+
} & RootFilterOperators<WithId<TSchema>>;
6161

6262
/** @public */
6363
export type Condition<T> = AlternativeType<T> | FilterOperators<AlternativeType<T>>;

test/types/community/collection/findX.test-d.ts

+9
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ interface SchemaWithTypicalId {
270270
const schemaWithTypicalIdCol = db.collection<SchemaWithTypicalId>('a');
271271
expectType<WithId<SchemaWithTypicalId> | null>(await schemaWithTypicalIdCol.findOne());
272272
expectAssignable<SchemaWithTypicalId | null>(await schemaWithTypicalIdCol.findOne());
273+
// should allow _id as an ObjectId
274+
await schemaWithTypicalIdCol.findOne({ _id: new ObjectId() });
275+
schemaWithTypicalIdCol.find({ _id: new ObjectId() });
273276

274277
interface SchemaWithOptionalTypicalId {
275278
_id?: ObjectId;
@@ -278,6 +281,9 @@ interface SchemaWithOptionalTypicalId {
278281
const schemaWithOptionalTypicalId = db.collection<SchemaWithOptionalTypicalId>('a');
279282
expectType<WithId<SchemaWithOptionalTypicalId> | null>(await schemaWithOptionalTypicalId.findOne());
280283
expectAssignable<SchemaWithOptionalTypicalId | null>(await schemaWithOptionalTypicalId.findOne());
284+
// should allow _id as an ObjectId
285+
await schemaWithTypicalIdCol.findOne({ _id: new ObjectId() });
286+
await schemaWithTypicalIdCol.find({ _id: new ObjectId() });
281287

282288
interface SchemaWithUserDefinedId {
283289
_id: number;
@@ -290,3 +296,6 @@ if (result !== null) {
290296
expectType<number>(result._id);
291297
}
292298
expectAssignable<SchemaWithUserDefinedId | null>(await schemaWithUserDefinedId.findOne());
299+
// should allow _id as a number
300+
await schemaWithUserDefinedId.findOne({ _id: 5 });
301+
await schemaWithUserDefinedId.find({ _id: 5 });

test/types/schema_helpers.test-d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ expectAssignable<InferIdType<{ _id: number } | { b: string }>>(1 + 1);
1919
// WithId
2020
expectAssignable<WithId<Document>>({ _id: new ObjectId() });
2121
expectAssignable<WithId<{ a: number }>>({ _id: new ObjectId(), a: 3 });
22+
expectAssignable<WithId<{ _id: ObjectId }>>({ _id: new ObjectId() });
23+
expectAssignable<WithId<{ _id: number }>>({ _id: 5 });
2224
expectNotType<WithId<Document>>({ _id: 3 });
2325

2426
// Changing _id to a type other than ObjectId makes it required:

test/types/union_schema.test-d.ts

+1-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { expectType, expectError, expectNotType, expectNotAssignable, expectAssi
22

33
import type { Collection } from '../../src/collection';
44
import { ObjectId } from '../../src/bson';
5-
import type { Filter, WithId } from '../../src/mongo_types';
5+
import type { WithId } from '../../src/mongo_types';
66

77
type InsertOneFirstParam<Schema> = Parameters<Collection<Schema>['insertOne']>[0];
88

@@ -44,23 +44,3 @@ interface B {
4444
type Data = A | B;
4545
expectAssignable<InsertOneFirstParam<Data>>({ _id: 2 });
4646
expectAssignable<InsertOneFirstParam<Data>>({ _id: 'hi' });
47-
48-
// Ensure Exclusive Union Type doesn't break inside our collection methods
49-
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
50-
// eslint-disable-next-line @typescript-eslint/ban-types
51-
type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
52-
53-
interface Dog {
54-
bark: string;
55-
}
56-
interface Cat {
57-
meow: string;
58-
}
59-
type Pet = XOR<Dog, Cat>;
60-
expectNotAssignable<InsertOneFirstParam<Pet>>({ meow: '', bark: '' });
61-
expectAssignable<InsertOneFirstParam<Pet>>({ meow: '' });
62-
expectAssignable<InsertOneFirstParam<Pet>>({ bark: '' });
63-
expectAssignable<InsertOneFirstParam<Pet>>({ bark: '', _id: new ObjectId() });
64-
expectNotAssignable<Filter<Pet>>({ meow: '', bark: '' }); // find
65-
expectAssignable<Filter<Pet>>({ bark: '' });
66-
expectAssignable<Filter<Pet>>({ meow: '' });

0 commit comments

Comments
 (0)