Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-3875): support recursive schema types #3433

Merged
merged 12 commits into from
Oct 13, 2022
2 changes: 1 addition & 1 deletion src/mongo_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export type MatchKeysAndValues<TSchema> = Readonly<
[Property in `${NestedPathsOfType<TSchema, Record<string, any>[]>}.$${
| `[${string}]`
| ''}.${string}`]?: any; // Could be further narrowed
}
} & Document
>;

/** @public */
Expand Down
4 changes: 2 additions & 2 deletions test/types/basic_schema.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';

import { ObjectId } from '../../src/bson';
import { Document, ObjectId } from '../../src/bson';
import { Collection } from '../../src/collection';
import { Db } from '../../src/db';
import { MongoClient } from '../../src/mongo_client';
Expand All @@ -20,7 +20,7 @@ expectType<Collection<ACounterWithId>>(new Collection<ACounterWithId>(db, ''));
////////////////////////////////////////////////////////////////////////////////////////////////////
// Simple Schema that does not define an _id
// With _id
type InsertOneArgOf<S> = Parameters<Collection<S>['insertOne']>[0];
type InsertOneArgOf<S extends Document> = Parameters<Collection<S>['insertOne']>[0];
dariakp marked this conversation as resolved.
Show resolved Hide resolved
expectAssignable<InsertOneArgOf<ACounter>>({ _id: new ObjectId(), a: 3 });
// Without _id
expectAssignable<InsertOneArgOf<ACounter>>({ a: 3 });
Expand Down
20 changes: 8 additions & 12 deletions test/types/community/collection/recursive-types.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,6 @@ expectNotAssignable<UpdateFilter<Author>>({
}
});

// Using keys that are beyond the permitted depth in $set still result in an error as opposed to falling back to any (known limitation)
expectNotAssignable<UpdateFilter<Author>>({
$set: {
'favoritePublication.author.favoritePublication.author.favoritePublication.author.favoritePublication.author.favoritePublication.author.name':
'name'
}
});

/**
* types that are not recursive in name but are recursive in structure are
* still supported
Expand Down Expand Up @@ -254,15 +246,19 @@ expectAssignable<Filter<A>>({
'b.c.d.a.b.c.d.a.b.name': 'a'
});

expectNotAssignable<Filter<A>>({
'b.c.d.a.b.c.d.a.b.name': 2
// Beyond the depth supported, there is no type checking
expectAssignable<Filter<A>>({
baileympearson marked this conversation as resolved.
Show resolved Hide resolved
'b.c.d.a.b.c.d.a.b.c.name': 3
});

expectAssignable<Filter<A>>({
'b.c.d.a.b.c.d.a.b.c.name': 2
});

// why does this blow up
expectNotAssignable<UpdateFilter<A>>({
expectAssignable<UpdateFilter<A>>({
$set: { 'b.c.d.a.b.c.d.a.b.name': 'a' }
});

expectAssignable<UpdateFilter<A>>({
$set: { 'b.c.d.a.b.c.d.a.b.c.name': 'a' }
});
10 changes: 8 additions & 2 deletions test/types/community/collection/updateX.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ expectError<UpdateFilter<TestModel>>({
$set: { 'subInterfaceField.nestedObject': { a: 1, b: '2' } }
});
expectError(buildUpdateFilter({ $set: { 'subInterfaceField.field2': 2 } }));
expectError(buildUpdateFilter({ $set: { 'unknown.field': null } }));

// NODE-3875 introduced intersection with Document to the MatchKeysAndValues so this no longer errors
// expectError(buildUpdateFilter({ $set: { 'unknown.field': null } }));
baileympearson marked this conversation as resolved.
Show resolved Hide resolved

expectAssignable<UpdateFilter<TestModel>>({ $set: { 'numberArray.$': 40 } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'numberArray.$[bla]': 40 } });
expectAssignable<UpdateFilter<TestModel>>({ $set: { 'numberArray.$[]': 1000.2 } });
Expand All @@ -241,7 +244,10 @@ expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { stringField: 'a' } }
expectError(buildUpdateFilter({ $setOnInsert: { stringField: 123 } }));
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'subInterfaceField.field1': '2' } });
expectError(buildUpdateFilter({ $setOnInsert: { 'subInterfaceField.field2': 2 } }));
expectError(buildUpdateFilter({ $setOnInsert: { 'unknown.field': null } }));

// NODE-3875 introduced intersection with Document to the MatchKeysAndValues so this no longer errors
// expectError(buildUpdateFilter({ $setOnInsert: { 'unknown.field': null } }));
baileympearson marked this conversation as resolved.
Show resolved Hide resolved

expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'numberArray.$': 40 } });
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'numberArray.$[bla]': 40 } });
expectAssignable<UpdateFilter<TestModel>>({ $setOnInsert: { 'numberArray.$[]': 1000.2 } });
Expand Down
4 changes: 2 additions & 2 deletions test/types/union_schema.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { expectAssignable, expectError, expectNotAssignable, expectNotType, expectType } from 'tsd';

import { ObjectId } from '../../src/bson';
import { Document, ObjectId } from '../../src/bson';
import type { Collection } from '../../src/collection';
import type { WithId } from '../../src/mongo_types';

type InsertOneFirstParam<Schema> = Parameters<Collection<Schema>['insertOne']>[0];
type InsertOneFirstParam<Schema extends Document> = Parameters<Collection<Schema>['insertOne']>[0];
baileympearson marked this conversation as resolved.
Show resolved Hide resolved

interface Circle {
_id: ObjectId;
Expand Down