feat(mongodb): add better return types for insertX functions (#38522)

This commit is contained in:
Hossein Saniei
2019-09-30 15:04:11 -07:00
committed by Michael Crane
parent 3d9e9bbdb7
commit fc4cbfd72f
2 changed files with 66 additions and 24 deletions
+31 -22
View File
@@ -32,7 +32,7 @@
/// <reference types="node" />
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<TSchema> = Omit<TSchema, '_id'> & { _id?: any };
type ExtractIdType<TSchema> =
TSchema extends { _id: infer U } // user has defined a type for _id
? ({} extends U ? Exclude<U, {}> : 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<TSchema> =
Omit<TSchema, '_id'> & { _id: ExtractIdType<TSchema> };
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html */
export interface Collection<TSchema = Default> {
/**
@@ -1005,19 +1014,19 @@ export interface Collection<TSchema = Default> {
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<TSchema>, callback: MongoCallback<InsertOneWriteOpResult>): void;
insert(docs: OptionalId<TSchema>, callback: MongoCallback<InsertWriteOpResult<WithId<TSchema>>>): void;
/** @deprecated Use insertOne, insertMany or bulkWrite */
insert(docs: OptionalId<TSchema>, options?: CollectionInsertOneOptions): Promise<InsertOneWriteOpResult>;
insert(docs: OptionalId<TSchema>, options?: CollectionInsertOneOptions): Promise<InsertWriteOpResult<WithId<TSchema>>>;
/** @deprecated Use insertOne, insertMany or bulkWrite */
insert(docs: OptionalId<TSchema>, options: CollectionInsertOneOptions, callback: MongoCallback<InsertOneWriteOpResult>): void;
insert(docs: OptionalId<TSchema>, options: CollectionInsertOneOptions, callback: MongoCallback<InsertWriteOpResult<WithId<TSchema>>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertMany */
insertMany(docs: Array<OptionalId<TSchema>>, callback: MongoCallback<InsertWriteOpResult>): void;
insertMany(docs: Array<OptionalId<TSchema>>, options?: CollectionInsertManyOptions): Promise<InsertWriteOpResult>;
insertMany(docs: Array<OptionalId<TSchema>>, options: CollectionInsertManyOptions, callback: MongoCallback<InsertWriteOpResult>): void;
insertMany(docs: Array<OptionalId<TSchema>>, callback: MongoCallback<InsertWriteOpResult<WithId<TSchema>>>): void;
insertMany(docs: Array<OptionalId<TSchema>>, options?: CollectionInsertManyOptions): Promise<InsertWriteOpResult<WithId<TSchema>>>;
insertMany(docs: Array<OptionalId<TSchema>>, options: CollectionInsertManyOptions, callback: MongoCallback<InsertWriteOpResult<WithId<TSchema>>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertOne */
insertOne(docs: OptionalId<TSchema>, callback: MongoCallback<InsertOneWriteOpResult>): void;
insertOne(docs: OptionalId<TSchema>, options?: CollectionInsertOneOptions): Promise<InsertOneWriteOpResult>;
insertOne(docs: OptionalId<TSchema>, options: CollectionInsertOneOptions, callback: MongoCallback<InsertOneWriteOpResult>): void;
insertOne(docs: OptionalId<TSchema>, callback: MongoCallback<InsertOneWriteOpResult<WithId<TSchema>>>): void;
insertOne(docs: OptionalId<TSchema>, options?: CollectionInsertOneOptions): Promise<InsertOneWriteOpResult<WithId<TSchema>>>;
insertOne(docs: OptionalId<TSchema>, options: CollectionInsertOneOptions, callback: MongoCallback<InsertOneWriteOpResult<WithId<TSchema>>>): void;
/** http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#isCapped */
isCapped(options?: { session: ClientSession }): Promise<any>;
isCapped(callback: MongoCallback<any>): 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<TSchema extends Record<string, any>> {
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<TSchema extends Record<string, any>> {
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<any>;
/** 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<any>, files: Collection<any>, 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 {
/**
+35 -2
View File
@@ -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<TestModel>('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<TestModelWithCustomId>('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; }
}