Skip to content

Commit f048e8e

Browse files
committed
fix: support positional array operator
The type-checking is not as strict as it could be
1 parent e41089b commit f048e8e

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

src/mongo_types.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,24 @@ export type OnlyFieldsOfType<TSchema, FieldType = any, AssignableType = FieldTyp
260260
/** @public */
261261
export type MatchKeysAndValues<TSchema> = Readonly<{
262262
[Property in Join<NestedPaths<TSchema>, '.'>]?: PropertyType<TSchema, Property>;
263-
}>;
263+
}> &
264+
// Positional array update operator
265+
Partial<
266+
Record<
267+
`${KeysOfAType<
268+
{
269+
[Property in Join<NestedPaths<TSchema>, '.'>]?: PropertyType<TSchema, Property>;
270+
},
271+
// Make sure the values for the keys are arrays
272+
any[]
273+
>}.$${`[${string}]` | ''}${
274+
// Subsequent nested path - could be narrowed
275+
`.${string}` | ''
276+
}`,
277+
// Value for updated field - could be narrowed
278+
any
279+
>
280+
>;
264281

265282
/** @public */
266283
export type AddToSetOperators<Type> = {

test/types/community/collection/bulkWrite.test-d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ collectionType.bulkWrite([
7474
update: {
7575
$set: {
7676
numberField: 123,
77-
'dot.notation': true
77+
'subInterfaceField.field1': 'true'
7878
}
7979
}
8080
}
@@ -123,7 +123,7 @@ collectionType.bulkWrite([
123123
update: {
124124
$set: {
125125
numberField: 123,
126-
'dot.notation': true
126+
'subInterfaceField.field2': 'true'
127127
}
128128
}
129129
}

test/types/community/collection/updateX.test-d.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import type {
2222
} from '../../../../src/mongo_types';
2323

2424
// MatchKeysAndValues - for basic mapping keys to their values, restricts that key types must be the same but optional, and permit dot array notation
25-
expectAssignable<MatchKeysAndValues<{ a: number; b: string }>>({ a: 2, 'dot.notation': true });
25+
expectAssignable<MatchKeysAndValues<{ a: number; b: string; c: { d: boolean } }>>({
26+
a: 2,
27+
'c.d': true
28+
});
2629
expectNotType<MatchKeysAndValues<{ a: number; b: string }>>({ b: 2 });
2730

2831
// AddToSetOperators
@@ -148,7 +151,7 @@ expectAssignable<UpdateFilter<TestModel>>({ $min: { doubleField: new Double(1.23
148151
expectAssignable<UpdateFilter<TestModel>>({ $min: { int32Field: new Int32(10) } });
149152
expectAssignable<UpdateFilter<TestModel>>({ $min: { longField: Long.fromString('999') } });
150153
expectAssignable<UpdateFilter<TestModel>>({ $min: { stringField: 'a' } });
151-
expectAssignable<UpdateFilter<TestModel>>({ $min: { 'dot.notation': 2 } });
154+
expectAssignable<UpdateFilter<TestModel>>({ $min: { 'subInterfaceField.field1': '2' } });
152155
expectAssignable<UpdateFilter<TestModel>>({ $min: { 'subInterfaceArray.$': 'string' } });
153156
expectAssignable<UpdateFilter<TestModel>>({ $min: { 'subInterfaceArray.$[bla]': 40 } });
154157
expectAssignable<UpdateFilter<TestModel>>({ $min: { 'subInterfaceArray.$[]': 1000.2 } });
@@ -163,7 +166,7 @@ expectAssignable<UpdateFilter<TestModel>>({ $max: { doubleField: new Double(1.23
163166
expectAssignable<UpdateFilter<TestModel>>({ $max: { int32Field: new Int32(10) } });
164167
expectAssignable<UpdateFilter<TestModel>>({ $max: { longField: Long.fromString('999') } });
165168
expectAssignable<UpdateFilter<TestModel>>({ $max: { stringField: 'a' } });
166-
expectAssignable<UpdateFilter<TestModel>>({ $max: { 'dot.notation': 2 } });
169+
expectAssignable<UpdateFilter<TestModel>>({ $max: { 'subInterfaceField.field1': '2' } });
167170
expectAssignable<UpdateFilter<TestModel>>({ $max: { 'subInterfaceArray.$': -10 } });
168171
expectAssignable<UpdateFilter<TestModel>>({ $max: { 'subInterfaceArray.$[bla]': 40 } });
169172
expectAssignable<UpdateFilter<TestModel>>({ $max: { 'subInterfaceArray.$[]': 1000.2 } });
@@ -192,7 +195,7 @@ expectAssignable<UpdateFilter<TestModel>>({ $set: { int32Field: new Int32(10) }
192195
expectAssignable<UpdateFilter<TestModel>>({ $set: { longField: Long.fromString('999') } });
193196
expectAssignable<UpdateFilter<TestModel>>({ $set: { stringField: 'a' } });
194197
expectError(buildUpdateFilter({ $set: { stringField: 123 } }));
195-
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'dot.notation': 2 } });
198+
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceField.field2': '2' } });
196199
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceArray.$': -10 } });
197200
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceArray.$[bla]': 40 } });
198201
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceArray.$[]': 1000.2 } });
@@ -206,7 +209,7 @@ expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { int32Field: new Int3
206209
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { longField: Long.fromString('999') } });
207210
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { stringField: 'a' } });
208211
expectError(buildUpdateFilter({ $setOnInsert: { stringField: 123 } }));
209-
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'dot.notation': 2 } });
212+
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'subInterfaceField.field1': '2' } });
210213
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'subInterfaceArray.$': -10 } });
211214
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'subInterfaceArray.$[bla]': 40 } });
212215
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'subInterfaceArray.$[]': 1000.2 } });

0 commit comments

Comments
 (0)