@@ -16,6 +16,11 @@ const db = client.db('test');
16
16
* Test the generic Filter using collection.find<T>() method
17
17
*/
18
18
19
+ interface HumanModel {
20
+ _id : ObjectId ;
21
+ name : string ;
22
+ }
23
+
19
24
// a collection model for all possible MongoDB BSON types and TypeScript types
20
25
interface PetModel {
21
26
_id : ObjectId ; // ObjectId field
@@ -24,14 +29,28 @@ interface PetModel {
24
29
age : number ; // number field
25
30
type : 'dog' | 'cat' | 'fish' ; // union field
26
31
isCute : boolean ; // boolean field
27
- bestFriend ?: PetModel ; // object field (Embedded/Nested Documents)
32
+ bestFriend ?: HumanModel ; // object field (Embedded/Nested Documents)
28
33
createdAt : Date ; // date field
29
34
treats : string [ ] ; // array of string
30
35
playTimePercent : Decimal128 ; // bson Decimal128 type
31
- readonly friends ?: ReadonlyArray < PetModel > ; // readonly array of objects
32
- playmates ?: PetModel [ ] ; // writable array of objects
36
+ readonly friends ?: ReadonlyArray < HumanModel > ; // readonly array of objects
37
+ playmates ?: HumanModel [ ] ; // writable array of objects
38
+ // Object with multiple nested levels
39
+ meta ?: {
40
+ updatedAt ?: Date ;
41
+ deep ?: {
42
+ nested ?: {
43
+ level ?: number ;
44
+ } ;
45
+ } ;
46
+ } ;
33
47
}
34
48
49
+ const john = {
50
+ _id : new ObjectId ( '577fa2d90c4cc47e31cf4b6a' ) ,
51
+ name : 'John'
52
+ } ;
53
+
35
54
const spot = {
36
55
_id : new ObjectId ( '577fa2d90c4cc47e31cf4b6f' ) ,
37
56
name : 'Spot' ,
@@ -83,14 +102,29 @@ expectNotType<Filter<PetModel>>({ age: [23, 43] });
83
102
84
103
/// it should query __nested document__ fields only by exact match
85
104
// TODO: we currently cannot enforce field order but field order is important for mongo
86
- await collectionT . find ( { bestFriend : spot } ) . toArray ( ) ;
105
+ await collectionT . find ( { bestFriend : john } ) . toArray ( ) ;
87
106
/// nested documents query should contain all required fields
88
- expectNotType < Filter < PetModel > > ( { bestFriend : { family : 'Andersons' } } ) ;
107
+ expectNotType < Filter < PetModel > > ( { bestFriend : { name : 'Andersons' } } ) ;
89
108
/// it should not accept wrong types for nested document fields
90
109
expectNotType < Filter < PetModel > > ( { bestFriend : 21 } ) ;
91
110
expectNotType < Filter < PetModel > > ( { bestFriend : 'Andersons' } ) ;
92
111
expectNotType < Filter < PetModel > > ( { bestFriend : [ spot ] } ) ;
93
- expectNotType < Filter < PetModel > > ( { bestFriend : [ { family : 'Andersons' } ] } ) ;
112
+ expectNotType < Filter < PetModel > > ( { bestFriend : [ { name : 'Andersons' } ] } ) ;
113
+
114
+ /// it should query __nested document__ fields using dot-notation
115
+ collectionT . find ( { 'meta.updatedAt' : new Date ( ) } ) ;
116
+ collectionT . find ( { 'meta.deep.nested.level' : 123 } ) ;
117
+ collectionT . find ( { 'friends.0.name' : 'John' } ) ;
118
+ collectionT . find ( { 'playmates.0.name' : 'John' } ) ;
119
+ /// it should not accept wrong types for nested document fields
120
+ expectNotType < Filter < PetModel > > ( { 'meta.updatedAt' : 123 } ) ;
121
+ expectNotType < Filter < PetModel > > ( { 'meta.updatedAt' : true } ) ;
122
+ expectNotType < Filter < PetModel > > ( { 'meta.updatedAt' : 'now' } ) ;
123
+ expectNotType < Filter < PetModel > > ( { 'meta.deep.nested.level' : '123' } ) ;
124
+ expectNotType < Filter < PetModel > > ( { 'meta.deep.nested.level' : true } ) ;
125
+ expectNotType < Filter < PetModel > > ( { 'meta.deep.nested.level' : new Date ( ) } ) ;
126
+ expectNotType < Filter < PetModel > > ( { 'friends.0.name' : 123 } ) ;
127
+ expectNotType < Filter < PetModel > > ( { 'playmates.0.name' : 123 } ) ;
94
128
95
129
/// it should query __array__ fields by exact match
96
130
await collectionT . find ( { treats : [ 'kibble' , 'bone' ] } ) . toArray ( ) ;
@@ -232,7 +266,3 @@ await collectionT.find({ playmates: { $elemMatch: { name: 'MrMeow' } } }).toArra
232
266
expectNotType < Filter < PetModel > > ( { name : { $all : [ 'world' , 'world' ] } } ) ;
233
267
expectNotType < Filter < PetModel > > ( { age : { $elemMatch : [ 1 , 2 ] } } ) ;
234
268
expectNotType < Filter < PetModel > > ( { type : { $size : 2 } } ) ;
235
-
236
- // dot key case that shows it is assignable even when the referenced key is the wrong type
237
- expectAssignable < Filter < PetModel > > ( { 'bestFriend.name' : 23 } ) ; // using dot notation permits any type for the key
238
- expectNotType < Filter < PetModel > > ( { bestFriend : { name : 23 } } ) ;
0 commit comments