Skip to content

Commit 8699cd6

Browse files
committed
types: avoid including document methods like $assertPopulated ProjectionType
1 parent f6545db commit 8699cd6

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

test/types/queries.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
import { ModifyResult, ObjectId } from 'mongodb';
2222
import { expectAssignable, expectError, expectNotAssignable, expectType } from 'tsd';
2323
import { autoTypedModel } from './models.test';
24-
import { AutoTypedSchemaType } from './schema.test';
2524

2625
interface QueryHelpers {
2726
_byName(this: QueryWithHelpers<any, ITest, QueryHelpers>, name: string): QueryWithHelpers<Array<ITest>, ITest, QueryHelpers>;
@@ -187,6 +186,7 @@ Test.find({}, { child: 1 }); // Dot notation should be able to use a combination
187186
expectError(Test.find({}, { 'docs.profiles': { name: 'aa' } })); // should support a combination of dot notation and objects
188187
expectError(Test.find({}, { endDate: { toString: 1 } }));
189188
expectError(Test.find({}, { tags: { trim: 1 } }));
189+
expectError(Test.find({}, { child: { toJSON: 1 } }));
190190

191191
// Manual Casting using ProjectionType
192192
Test.find({}, { docs: { unknownParams: 1 } } as ProjectionType<ITest>);

types/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,8 @@ declare module 'mongoose' {
684684
}
685685
: Element;
686686
type _IDType = { _id?: boolean | 1 | 0 };
687-
type InclusionProjection<T> = IsItRecordAndNotAny<T> extends true ? Projector<WithLevel1NestedPaths<T>, true | 1> & _IDType : AnyObject;
688-
type ExclusionProjection<T> = IsItRecordAndNotAny<T> extends true ? Projector<WithLevel1NestedPaths<T>, false | 0> & _IDType : AnyObject;
687+
export type InclusionProjection<T> = IsItRecordAndNotAny<T> extends true ? Projector<WithLevel1NestedPaths<T>, true | 1> & _IDType : AnyObject;
688+
export type ExclusionProjection<T> = IsItRecordAndNotAny<T> extends true ? Projector<WithLevel1NestedPaths<T>, false | 0> & _IDType : AnyObject;
689689

690690
export type ProjectionType<T> = (InclusionProjection<T> & AnyObject) | (ExclusionProjection<T> & AnyObject) | string;
691691
export type SortValues = SortOrder;

types/utility.d.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ declare module 'mongoose' {
44

55
type WithLevel1NestedPaths<T, K extends keyof T = keyof T> = {
66
[P in K | NestedPaths<Required<T>, K>]: P extends K
7-
? NonNullable<T[P]>
7+
// Handle top-level paths
8+
// First, drill into documents so we don't end up surfacing `$assertPopulated`, etc.
9+
? Extract<NonNullable<T[P]>, Document> extends never
10+
// If not a document, then return the type. Otherwise, get the DocType.
11+
? NonNullable<T[P]>
12+
: Extract<NonNullable<T[P]>, Document> extends Document<any, any, infer DocType, any>
13+
? DocType
14+
: never
15+
// Handle nested paths
816
: P extends `${infer Key}.${infer Rest}`
917
? Key extends keyof T
1018
? T[Key] extends (infer U)[]
@@ -21,13 +29,19 @@ declare module 'mongoose' {
2129
type NestedPaths<T, K extends keyof T> = K extends string
2230
? T[K] extends TreatAsPrimitives
2331
? never
24-
: T[K] extends Array<infer U>
25-
? U extends Record<string, any>
26-
? `${K}.${keyof NonNullable<U> & string}`
27-
: never
28-
: T[K] extends Record<string, any> | null | undefined
29-
? `${K}.${keyof NonNullable<T[K]> & string}`
30-
: never
32+
: Extract<NonNullable<T[K]>, Document> extends never
33+
? T[K] extends Array<infer U>
34+
? U extends Record<string, any>
35+
? `${K}.${keyof NonNullable<U> & string}`
36+
: never
37+
: T[K] extends Record<string, any> | null | undefined
38+
? `${K}.${keyof NonNullable<T[K]> & string}`
39+
: never
40+
: Extract<NonNullable<T[K]>, Document> extends Document<any, any, infer DocType, any>
41+
? DocType extends Record<string, any>
42+
? `${K}.${keyof NonNullable<DocType> & string}`
43+
: never
44+
: never
3145
: never;
3246

3347
type WithoutUndefined<T> = T extends undefined ? never : T;

0 commit comments

Comments
 (0)