|
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