Skip to content

Commit ba58200

Browse files
committed
test: show internal type usage with additional tests
1 parent 3017cc4 commit ba58200

File tree

5 files changed

+53
-29
lines changed

5 files changed

+53
-29
lines changed

CONTRIBUTORS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
- Neal Beeken <<[email protected]>>
5858
- Eric Adum <<[email protected]>>
59-
- Durran Jordan <<durran.jordan@mongodb.com>>
59+
- Durran Jordan <<durran@gmail.com>>
6060

6161
## Community Types
6262

test/types/basic_schema.test-d.ts

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,67 @@
1-
import { expectType } from 'tsd';
1+
import { expectAssignable, expectNotType, expectType } from 'tsd';
22

33
import { Collection } from '../../src/collection';
4-
import type { ObjectId } from '../../src/bson';
4+
import { ObjectId } from '../../src/bson';
55
import { Db } from '../../src/db';
66
import { MongoClient } from '../../src/mongo_client';
77
import type { InferIdType } from '../../src/mongo_types';
88

99
const db = new Db(new MongoClient(''), '');
1010

11-
type InsertRes<TId = ObjectId> = Promise<{ acknowledged: boolean; insertedId: TId }>;
11+
type ACounter = { a: number };
12+
type ACounterWithId = { a: number; _id: ObjectId };
1213

1314
////////////////////////////////////////////////////////////////////////////////////////////////////
1415
// Can defined Schema without _id
15-
expectType<Collection<{ a: number }>>(new Collection<{ a: number }>(db, ''));
16+
expectType<Collection<ACounter>>(new Collection<ACounter>(db, ''));
17+
// Or with one
18+
expectType<Collection<ACounterWithId>>(new Collection<ACounterWithId>(db, ''));
1619

1720
////////////////////////////////////////////////////////////////////////////////////////////////////
18-
// Simple Schema
19-
const simpleC = new Collection<{ a: number; _id: ObjectId }>(db, '');
20-
expectType<InsertRes>(simpleC.insertOne({ a: 2 }));
21+
// Simple Schema that does not define an _id
22+
// With _id
23+
type InsertOneArgOf<S> = Parameters<Collection<S>['insertOne']>[0];
24+
expectAssignable<InsertOneArgOf<ACounter>>({ _id: new ObjectId(), a: 3 });
25+
// Without _id
26+
expectAssignable<InsertOneArgOf<ACounter>>({ a: 3 });
27+
// Does not permit extra keys
28+
expectNotType<InsertOneArgOf<ACounter>>({ a: 2, b: 34 });
29+
////////////////////////////////////////////////////////////////////////////////////////////////////
30+
// Simple Schema that does define an _id
31+
// With _id
32+
expectAssignable<InsertOneArgOf<ACounterWithId>>({ _id: new ObjectId(), a: 3 });
33+
// Without _id
34+
expectAssignable<InsertOneArgOf<ACounterWithId>>({ a: 3 });
35+
// Does not permit extra keys
36+
expectNotType<InsertOneArgOf<ACounterWithId>>({ a: 2, b: 34 });
2137

2238
////////////////////////////////////////////////////////////////////////////////////////////////////
23-
// CustomType _id Schema
39+
// CustomType _id Schema (behavior change)
40+
// _id that is a custom type must be generated client side, so it is required
2441
class MyId {
2542
uuid!: number;
2643
}
2744
interface CustomIdType {
2845
a: number;
2946
_id: MyId;
3047
}
31-
const customIdTypeC = new Collection<CustomIdType>(db, '');
48+
type customIdCollection = Collection<CustomIdType>;
49+
type insertOneArg = Parameters<customIdCollection['insertOne']>[0];
50+
51+
// inferring the _id type is straight forward for a schema like this
3252
type IdType = InferIdType<CustomIdType>;
3353
expectType<IdType>(new MyId());
34-
expectType<InsertRes<MyId>>(customIdTypeC.insertOne({ a: 2, _id: new MyId() }));
54+
55+
// _id is a required field since it isn't an ObjectId
56+
expectAssignable<insertOneArg>({ a: 2, _id: new MyId() });
57+
expectNotType<insertOneArg>({ a: 2 });
58+
59+
////////////////////////////////////////////////////////////////////////////////////////////////////
60+
// InferIdType -
61+
// eslint-disable-next-line @typescript-eslint/ban-types
62+
type Empty = {};
63+
const a: never = 0 as never;
64+
const oid = new ObjectId();
65+
expectType<InferIdType<Empty>>(oid); // Empty schema gets the implicit _id
66+
expectType<InferIdType<{ _id: Empty }>>(a); // Empty object as an oid resolves to never, while this is a valid _id, it is likely undesirable
67+
expectType<InferIdType<{ _id: { a: number } }>>({ a: 3 }); // embedded documents are permitted as _id fields

test/types/distinct.test-d.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { expectType } from 'tsd';
22

3-
import { Db } from '../../src/db';
4-
import { MongoClient } from '../../src/mongo_client';
3+
import type { Collection } from '../../src/collection';
54
import type { Movie } from './example_schemas';
65

7-
const db = new Db(new MongoClient(''), '');
8-
const collection = db.collection<Movie>('');
9-
106
// Ensure distinct takes all keys of the schema plus '_id'
11-
const x = (null as unknown) as Parameters<typeof collection.distinct>[0];
7+
const x = (null as unknown) as Parameters<Collection<Movie>['distinct']>[0];
128
expectType<'_id' | keyof Movie>(x);

test/types/mongodb.test-d.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
import { expectDeprecated, expectType } from 'tsd';
1+
import { expectDeprecated } from 'tsd';
22

3-
import { Collection } from '../../src//collection';
4-
import { AggregationCursor } from '../../src//cursor/aggregation_cursor';
5-
import { Db } from '../../src//db';
6-
import { MongoError } from '../../src//error';
7-
import { MongoClient } from '../../src//mongo_client';
3+
import { Collection } from '../../src/collection';
4+
import { AggregationCursor } from '../../src/cursor/aggregation_cursor';
5+
import { MongoError } from '../../src/error';
86

7+
// We wish to keep these APIs but continue to ensure they are marked as deprecated.
98
expectDeprecated(Collection.prototype.insert);
109
expectDeprecated(Collection.prototype.update);
1110
expectDeprecated(Collection.prototype.remove);
1211
expectDeprecated(Collection.prototype.count);
1312
expectDeprecated(MongoError.create);
1413
expectDeprecated(AggregationCursor.prototype.geoNear);
15-
16-
const db = new Db(new MongoClient(''), '');
17-
18-
expectType<Collection<{ a: number }>>(db.collection<{ a: number }>(''));

test/types/union_schema.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { expectType, expectError, expectNotType, expectNotAssignable } from 'tsd
22

33
import { Collection } from '../../src/collection';
44
import { ObjectId } from '../../src/bson';
5-
import { Db } from '../../src//db';
6-
import { MongoClient } from '../../src//mongo_client';
5+
import { Db } from '../../src/db';
6+
import { MongoClient } from '../../src/mongo_client';
77

88
type InsertRes<TId = ObjectId> = Promise<{ acknowledged: boolean; insertedId: TId }>;
99

0 commit comments

Comments
 (0)