diff --git a/src/bulk/common.ts b/src/bulk/common.ts index d25fe09753..a1dd1c700b 100644 --- a/src/bulk/common.ts +++ b/src/bulk/common.ts @@ -33,7 +33,7 @@ import type { Collection } from '../collection'; import type { Topology } from '../sdam/topology'; import type { CommandOperationOptions, CollationOptions } from '../operations/command'; import type { Hint } from '../operations/operation'; -import type { Filter, OneOrMore, OptionalId, UpdateFilter } from '../mongo_types'; +import type { Filter, OneOrMore, WithoutId, OptionalId, UpdateFilter } from '../mongo_types'; /** @internal */ const kServerError = Symbol('serverError'); @@ -79,7 +79,7 @@ export interface ReplaceOneModel { /** The filter to limit the replaced document. */ filter: Filter; /** The document with which to replace the matched document. */ - replacement: TSchema; + replacement: WithoutId; /** Specifies a collation. */ collation?: CollationOptions; /** The index to use. If specified, then the query system will only consider plans using the hinted index. */ diff --git a/src/collection.ts b/src/collection.ts index 7aae0901c3..703e00cd97 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -93,6 +93,7 @@ import type { TODO_NODE_3286, UpdateFilter, WithId, + WithoutId, OptionalId, Flatten } from './mongo_types'; @@ -459,26 +460,29 @@ export class Collection { * @param options - Optional settings for the command * @param callback - An optional callback, a Promise will be returned if none is provided */ - replaceOne(filter: Filter, replacement: TSchema): Promise; replaceOne( filter: Filter, - replacement: TSchema, + replacement: WithoutId + ): Promise; + replaceOne( + filter: Filter, + replacement: WithoutId, callback: Callback ): void; replaceOne( filter: Filter, - replacement: TSchema, + replacement: WithoutId, options: ReplaceOptions ): Promise; replaceOne( filter: Filter, - replacement: TSchema, + replacement: WithoutId, options: ReplaceOptions, callback: Callback ): void; replaceOne( filter: Filter, - replacement: TSchema, + replacement: WithoutId, options?: ReplaceOptions | Callback, callback?: Callback ): Promise | void { @@ -1279,26 +1283,29 @@ export class Collection { * @param options - Optional settings for the command * @param callback - An optional callback, a Promise will be returned if none is provided */ - findOneAndReplace(filter: Filter, replacement: Document): Promise>; findOneAndReplace( filter: Filter, - replacement: Document, + replacement: WithoutId + ): Promise>; + findOneAndReplace( + filter: Filter, + replacement: WithoutId, callback: Callback> ): void; findOneAndReplace( filter: Filter, - replacement: Document, + replacement: WithoutId, options: FindOneAndReplaceOptions ): Promise>; findOneAndReplace( filter: Filter, - replacement: Document, + replacement: WithoutId, options: FindOneAndReplaceOptions, callback: Callback> ): void; findOneAndReplace( filter: Filter, - replacement: Document, + replacement: WithoutId, options?: FindOneAndReplaceOptions | Callback>, callback?: Callback> ): Promise> | void { diff --git a/test/types/community/collection/bulkWrite.test-d.ts b/test/types/community/collection/bulkWrite.test-d.ts index 82f9e6aae5..9502d965ad 100644 --- a/test/types/community/collection/bulkWrite.test-d.ts +++ b/test/types/community/collection/bulkWrite.test-d.ts @@ -181,6 +181,38 @@ collectionType.bulkWrite([ } } ]); +// allow a literal replacement doc without an _id +collectionType.bulkWrite([ + { + replaceOne: { + filter: {}, + replacement: { + dateField: new Date(), + fruitTags: [], + numberField: 0, + readonlyFruitTags: [], + stringField: 'string', + subInterfaceArray: [], + subInterfaceField: { field1: '1', field2: '2' } + }, + upsert: true + } + } +]); +// disallow a literal replacement doc with an _id +expectError( + collectionType.bulkWrite([ + { + replaceOne: { + filter: {}, + replacement: { + _id: new ObjectId() + }, + upsert: true + } + } + ]) +); expectError( collectionType.bulkWrite([ diff --git a/test/types/community/collection/replaceX.test-d.ts b/test/types/community/collection/replaceX.test-d.ts new file mode 100644 index 0000000000..6bd2e8c081 --- /dev/null +++ b/test/types/community/collection/replaceX.test-d.ts @@ -0,0 +1,19 @@ +import { expectError } from 'tsd'; +import { MongoClient, ObjectId } from '../../../../src'; + +// test collection.replaceX functions +const client = new MongoClient(''); +const db = client.db('test'); + +interface TestModel { + _id: ObjectId; + stringField: string; +} + +const collection = db.collection('testCollection'); + +// should accept a replacement doc without an _id +await collection.replaceOne({}, { stringField: 'b' }); + +// should not accept a literal replacement doc with an _id +expectError(await collection.replaceOne({}, { _id: new ObjectId(), stringField: 'a' }));