diff --git a/types/mongodb/index.d.ts b/types/mongodb/index.d.ts
index 6f43aa22c9..6f372ba084 100644
--- a/types/mongodb/index.d.ts
+++ b/types/mongodb/index.d.ts
@@ -32,7 +32,7 @@
///
-import { Binary, ObjectID, Timestamp } from 'bson';
+import { Binary, ObjectId, Timestamp } from 'bson';
import { EventEmitter } from 'events';
import { Readable, Writable } from "stream";
import { checkServerIdentity } from "tls";
@@ -857,6 +857,15 @@ export interface FSyncOptions extends CommonOptions {
type OptionalId = Omit & { _id?: any };
+type ExtractIdType =
+ TSchema extends { _id: infer U } // user has defined a type for _id
+ ? ({} extends U ? Exclude : U) // Exclude is used here to fix typescript 2 bug when TSchema is "any"
+ : ObjectId; // user has not defined _id on schema
+
+// this adds _id as required property
+type WithId =
+ Omit & { _id: ExtractIdType };
+
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html */
export interface Collection {
/**
@@ -1005,19 +1014,19 @@ export interface Collection {
initializeUnorderedBulkOp(options?: CommonOptions): UnorderedBulkOperation;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertOne */
/** @deprecated Use insertOne, insertMany or bulkWrite */
- insert(docs: OptionalId, callback: MongoCallback): void;
+ insert(docs: OptionalId, callback: MongoCallback>>): void;
/** @deprecated Use insertOne, insertMany or bulkWrite */
- insert(docs: OptionalId, options?: CollectionInsertOneOptions): Promise;
+ insert(docs: OptionalId, options?: CollectionInsertOneOptions): Promise>>;
/** @deprecated Use insertOne, insertMany or bulkWrite */
- insert(docs: OptionalId, options: CollectionInsertOneOptions, callback: MongoCallback): void;
+ insert(docs: OptionalId, options: CollectionInsertOneOptions, callback: MongoCallback>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertMany */
- insertMany(docs: Array>, callback: MongoCallback): void;
- insertMany(docs: Array>, options?: CollectionInsertManyOptions): Promise;
- insertMany(docs: Array>, options: CollectionInsertManyOptions, callback: MongoCallback): void;
+ insertMany(docs: Array>, callback: MongoCallback>>): void;
+ insertMany(docs: Array>, options?: CollectionInsertManyOptions): Promise>>;
+ insertMany(docs: Array>, options: CollectionInsertManyOptions, callback: MongoCallback>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertOne */
- insertOne(docs: OptionalId, callback: MongoCallback): void;
- insertOne(docs: OptionalId, options?: CollectionInsertOneOptions): Promise;
- insertOne(docs: OptionalId, options: CollectionInsertOneOptions, callback: MongoCallback): void;
+ insertOne(docs: OptionalId, callback: MongoCallback>>): void;
+ insertOne(docs: OptionalId, options?: CollectionInsertOneOptions): Promise>>;
+ insertOne(docs: OptionalId, options: CollectionInsertOneOptions, callback: MongoCallback>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#isCapped */
isCapped(options?: { session: ClientSession }): Promise;
isCapped(callback: MongoCallback): void;
@@ -1730,10 +1739,10 @@ export interface FindOneOptions {
}
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~insertWriteOpResult */
-export interface InsertWriteOpResult {
+export interface InsertWriteOpResult> {
insertedCount: number;
- ops: any[];
- insertedIds: { [key: number]: ObjectID };
+ ops: TSchema[];
+ insertedIds: { [key: number]: TSchema['_id'] };
connection: any;
result: { ok: number, n: number };
}
@@ -1751,10 +1760,10 @@ export interface CollectionInsertOneOptions extends CommonOptions {
}
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~insertOneWriteOpResult */
-export interface InsertOneWriteOpResult {
+export interface InsertOneWriteOpResult> {
insertedCount: number;
- ops: any[];
- insertedId: ObjectID;
+ ops: TSchema[];
+ insertedId: TSchema['_id'];
connection: any;
result: { ok: number, n: number };
}
@@ -1792,7 +1801,7 @@ export interface UpdateWriteOpResult {
matchedCount: number;
modifiedCount: number;
upsertedCount: number;
- upsertedId: { _id: ObjectID };
+ upsertedId: { _id: ObjectId };
}
/** https://github.com/mongodb/node-mongodb-native/blob/2.2/lib/collection.js#L957 */
@@ -2037,13 +2046,13 @@ export class CommandCursor extends Readable {
export class GridFSBucket {
constructor(db: Db, options?: GridFSBucketOptions);
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#delete */
- delete(id: ObjectID, callback?: GridFSBucketErrorCallback): void;
+ delete(id: ObjectId, callback?: GridFSBucketErrorCallback): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#drop */
drop(callback?: GridFSBucketErrorCallback): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#find */
find(filter?: object, options?: GridFSBucketFindOptions): Cursor;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#openDownloadStream */
- openDownloadStream(id: ObjectID, options?: { start: number, end: number }): GridFSBucketReadStream;
+ openDownloadStream(id: ObjectId, options?: { start: number, end: number }): GridFSBucketReadStream;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#openDownloadStreamByName */
openDownloadStreamByName(filename: string, options?: { revision: number, start: number, end: number }): GridFSBucketReadStream;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#openUploadStream */
@@ -2051,7 +2060,7 @@ export class GridFSBucket {
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#openUploadStreamWithId */
openUploadStreamWithId(id: GridFSBucketWriteStreamId, filename: string, options?: GridFSBucketOpenUploadStreamOptions): GridFSBucketWriteStream;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html#rename */
- rename(id: ObjectID, filename: string, callback?: GridFSBucketErrorCallback): void;
+ rename(id: ObjectId, filename: string, callback?: GridFSBucketErrorCallback): void;
}
/** http://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucket.html */
@@ -2087,7 +2096,7 @@ export interface GridFSBucketOpenUploadStreamOptions {
/** https://mongodb.github.io/node-mongodb-native/3.1/api/GridFSBucketReadStream.html */
export class GridFSBucketReadStream extends Readable {
- id: ObjectID;
+ id: ObjectId;
constructor(chunks: Collection, files: Collection, readPreference: object, filter: object, options?: GridFSBucketReadStreamOptions);
}
@@ -2154,7 +2163,7 @@ export interface ChangeStreamOptions {
startAfter?: object;
}
-type GridFSBucketWriteStreamId = string | number | object | ObjectID;
+type GridFSBucketWriteStreamId = string | number | object | ObjectId;
export interface LoggerOptions {
/**
diff --git a/types/mongodb/test/collection/insertX.ts b/types/mongodb/test/collection/insertX.ts
index fe70ccc092..bb4f6e8f21 100644
--- a/types/mongodb/test/collection/insertX.ts
+++ b/types/mongodb/test/collection/insertX.ts
@@ -1,5 +1,6 @@
import { connect } from 'mongodb';
import { connectionString } from '../index';
+import { ObjectId } from 'bson';
// test collection.insertX functions
async function run() {
@@ -20,13 +21,45 @@ async function run() {
numberField?: number;
fruitTags: string[];
}
+ type TestModelWithId = TestModel & { _id: ObjectId; };
const collection = db.collection('testCollection');
- collection.insertOne({
+ const result = await collection.insert({
stringField: 'hola',
fruitTags: ['Strawberry'],
});
- collection.insertMany([
+ const resultOne = await collection.insertOne({
+ stringField: 'hola',
+ fruitTags: ['Strawberry'],
+ });
+ const resultMany = await collection.insertMany([
{ stringField: 'hola', fruitTags: ['Apple', 'Lemon'] },
{ stringField: 'hola', numberField: 1, fruitTags: [] },
]);
+
+ // test results type
+ // should add a _id field with ObjectId type if it does not exist on collection type
+ result.ops[0]._id; // $ExpectType ObjectId
+ resultMany.ops[0]._id; // $ExpectType ObjectId
+ resultOne.ops[0]._id; // $ExpectType ObjectId
+ result.insertedIds; // $ExpectType { [key: number]: ObjectId; }
+ resultMany.insertedIds; // $ExpectType { [key: number]: ObjectId; }
+ resultOne.insertedId; // $ExpectType ObjectId
+
+ // should add a _id field with user specified type
+ type TestModelWithCustomId = TestModel & { _id: number; };
+ const collectionWithId = db.collection('testCollection');
+
+ const resultOneWithId = await collectionWithId.insertOne({
+ stringField: 'hola',
+ fruitTags: ['Strawberry'],
+ });
+ const resultManyWithId = await collectionWithId.insertMany([
+ { stringField: 'hola', fruitTags: ['Apple', 'Lemon'] },
+ { stringField: 'hola', numberField: 1, fruitTags: [] },
+ ]);
+
+ resultOneWithId.ops[0]._id; // $ExpectType number
+ resultOneWithId.insertedId; // $ExpectType number
+ resultManyWithId.ops[0]._id; // $ExpectType number
+ resultManyWithId.insertedIds; // $ExpectType { [key: number]: number; }
}