|
1 |
| -import { expectType } from 'tsd'; |
| 1 | +import { expectAssignable, expectNotType, expectType } from 'tsd'; |
2 | 2 |
|
3 | 3 | import { Collection } from '../../src/collection';
|
4 |
| -import type { ObjectId } from '../../src/bson'; |
| 4 | +import { ObjectId } from '../../src/bson'; |
5 | 5 | import { Db } from '../../src/db';
|
6 | 6 | import { MongoClient } from '../../src/mongo_client';
|
7 | 7 | import type { InferIdType } from '../../src/mongo_types';
|
8 | 8 |
|
9 | 9 | const db = new Db(new MongoClient(''), '');
|
10 | 10 |
|
11 |
| -type InsertRes<TId = ObjectId> = Promise<{ acknowledged: boolean; insertedId: TId }>; |
| 11 | +type ACounter = { a: number }; |
| 12 | +type ACounterWithId = { a: number; _id: ObjectId }; |
12 | 13 |
|
13 | 14 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
14 | 15 | // 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, '')); |
16 | 19 |
|
17 | 20 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
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 }); |
21 | 37 |
|
22 | 38 | ////////////////////////////////////////////////////////////////////////////////////////////////////
|
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 |
24 | 41 | class MyId {
|
25 | 42 | uuid!: number;
|
26 | 43 | }
|
27 | 44 | interface CustomIdType {
|
28 | 45 | a: number;
|
29 | 46 | _id: MyId;
|
30 | 47 | }
|
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 |
32 | 52 | type IdType = InferIdType<CustomIdType>;
|
33 | 53 | 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 |
0 commit comments