Skip to content

Commit

Permalink
fix(NODE-4423): better type support for nested objects in query & upd…
Browse files Browse the repository at this point in the history
…ate (#3328)
  • Loading branch information
coyotte508 committed Jul 20, 2022
1 parent 7613d4b commit 05e007b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/mongo_types.ts
Expand Up @@ -531,7 +531,7 @@ export type NestedPaths<Type> = Type extends
: // child is an array, but it's not a recursive array
[Key, ...NestedPaths<Type[Key]>]
: // child is not structured the same as the parent
[Key, ...NestedPaths<Type[Key]>];
[Key, ...NestedPaths<Type[Key]>] | [Key];
}[Extract<keyof Type, string>]
: [];

Expand Down
3 changes: 3 additions & 0 deletions test/types/community/collection/filterQuery.test-d.ts
Expand Up @@ -178,6 +178,7 @@ expectNotType<Filter<PetModel>>({ 'regex.dotAll': true });
collectionT.find({ 'meta.updatedAt': new Date() });
collectionT.find({ 'meta.deep.nested.level': 123 });
collectionT.find({ meta: { deep: { nested: { level: 123 } } } }); // no impact on actual nesting
collectionT.find({ 'meta.deep': { nested: { level: 123 } } });
collectionT.find({ 'friends.0.name': 'John' });
collectionT.find({ 'playmates.0.name': 'John' });
// supports arrays with primitive types
Expand All @@ -203,6 +204,8 @@ expectNotType<Filter<PetModel>>({ 'friends.0.name': 123 });
expectNotType<Filter<PetModel>>({ 'playmates.0.name': 123 });
expectNotType<Filter<PetModel>>({ 'laps.foo': 'string' });
expectNotType<Filter<PetModel>>({ 'treats.0': 123 });
expectNotType<Filter<PetModel>>({ meta: { deep: { nested: { level: 'string' } } } });
expectNotType<Filter<PetModel>>({ 'meta.deep': { nested: { level: 'string' } } });

/// it should not accept wrong types for nested document array fields
expectError<Filter<PetModel>>({
Expand Down
16 changes: 16 additions & 0 deletions test/types/community/collection/updateX.test-d.ts
Expand Up @@ -74,6 +74,10 @@ interface SubTestModel {
field1: string;
field2?: string;
field3?: number;
nestedObject?: {
a: string;
b: string;
};
}

type FruitTypes = 'apple' | 'pear';
Expand All @@ -97,6 +101,7 @@ interface TestModel {
subInterfaceField: SubTestModel;
subInterfaceArray: SubTestModel[];
timestampField: Timestamp;
extras: Record<string, { id: string }>;
}
const collectionTType = db.collection<TestModel>('test.update');

Expand Down Expand Up @@ -201,9 +206,20 @@ expectAssignable<UpdateFilter<TestModel>>({
expectAssignable<UpdateFilter<TestModel>>({ $set: { doubleField: new Double(1.23) } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { int32Field: new Int32(10) } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { longField: Long.fromString('999') } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { extras: { someExtras: { id: 'someId' } } } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { stringField: 'a' } });
expectError(buildUpdateFilter({ $set: { stringField: 123 } }));
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceField.field2': '2' } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'subInterfaceField.nestedObject.a': '2' } });
expectAssignable<UpdateFilter<TestModel>>({
$set: { 'subInterfaceField.nestedObject': { a: '1', b: '2' } }
});
expectError<UpdateFilter<TestModel>>({
$set: { 'subInterfaceField.nestedObject': { a: '1' } }
});
expectError<UpdateFilter<TestModel>>({
$set: { 'subInterfaceField.nestedObject': { a: 1, b: '2' } }
});
expectError(buildUpdateFilter({ $set: { 'subInterfaceField.field2': 2 } }));
expectError(buildUpdateFilter({ $set: { 'unknown.field': null } }));
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'numberArray.$': 40 } });
Expand Down

0 comments on commit 05e007b

Please sign in to comment.