@@ -56,8 +56,9 @@ export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
5656
5757/** A MongoDB filter can be some portion of the schema or a set of operators @public */
5858export type Filter < TSchema > = {
59- [ P in keyof TSchema ] ?: Condition < TSchema [ P ] > ;
60- } & RootFilterOperators < TSchema > ;
59+ [ P in Join < NestedPaths < TSchema > , '.' > ] ?: Condition < PropertyType < TSchema , P > > ;
60+ } &
61+ RootFilterOperators < TSchema > ;
6162
6263/** @public */
6364export type Condition < T > = AlternativeType < T > | FilterOperators < AlternativeType < T > > ;
@@ -256,7 +257,8 @@ export type SetFields<TSchema> = ({
256257 readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > | undefined > ] ?:
257258 | OptionalId < Flatten < TSchema [ key ] > >
258259 | AddToSetOperators < Array < OptionalId < Flatten < TSchema [ key ] > > > > ;
259- } & NotAcceptedFields < TSchema , ReadonlyArray < any > | undefined > ) & {
260+ } &
261+ NotAcceptedFields < TSchema , ReadonlyArray < any > | undefined > ) & {
260262 readonly [ key : string ] : AddToSetOperators < any > | any ;
261263} ;
262264
@@ -265,7 +267,8 @@ export type PushOperator<TSchema> = ({
265267 readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?:
266268 | Flatten < TSchema [ key ] >
267269 | ArrayOperator < Array < Flatten < TSchema [ key ] > > > ;
268- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
270+ } &
271+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
269272 readonly [ key : string ] : ArrayOperator < any > | any ;
270273} ;
271274
@@ -274,14 +277,16 @@ export type PullOperator<TSchema> = ({
274277 readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?:
275278 | Partial < Flatten < TSchema [ key ] > >
276279 | FilterOperations < Flatten < TSchema [ key ] > > ;
277- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
280+ } &
281+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
278282 readonly [ key : string ] : FilterOperators < any > | any ;
279283} ;
280284
281285/** @public */
282286export type PullAllOperator < TSchema > = ( {
283287 readonly [ key in KeysOfAType < TSchema , ReadonlyArray < any > > ] ?: TSchema [ key ] ;
284- } & NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
288+ } &
289+ NotAcceptedFields < TSchema , ReadonlyArray < any > > ) & {
285290 readonly [ key : string ] : ReadonlyArray < any > ;
286291} ;
287292
@@ -422,3 +427,50 @@ export class TypedEventEmitter<Events extends EventsDescription> extends EventEm
422427
423428/** @public */
424429export class CancellationToken extends TypedEventEmitter < { cancel ( ) : void } > { }
430+
431+ /**
432+ * Helper types for dot-notation filter attributes
433+ */
434+
435+ // export type ArrayType<Type> = Type extends Array<infer Value> ? Value : never;
436+
437+ /** @public */
438+ export type Join < T extends unknown [ ] , D extends string > = T extends [ ]
439+ ? ''
440+ : T extends [ string | number ]
441+ ? `${T [ 0 ] } `
442+ : T extends [ string | number , ...infer R ]
443+ ? `${T [ 0 ] } ${D } ${Join < R , D > } `
444+ : string | number ;
445+
446+ /** @public */
447+ export type PropertyType < Type , Property extends string > = string extends Property
448+ ? unknown
449+ : Property extends keyof Type
450+ ? Type [ Property ]
451+ : Property extends `${infer Key } .${infer Rest } `
452+ ? Key extends `${number } `
453+ ? Type extends Array < infer ArrayType >
454+ ? PropertyType < ArrayType , Rest >
455+ : Type extends ReadonlyArray < infer ArrayType >
456+ ? PropertyType < ArrayType , Rest >
457+ : unknown
458+ : Key extends keyof Type
459+ ? PropertyType < Type [ Key ] , Rest >
460+ : unknown
461+ : unknown ;
462+
463+ // We dont't support nested circular references
464+ /** @public */
465+ export type NestedPaths < Type > = Type extends string | number | boolean | Date | ObjectId
466+ ? [ ]
467+ : Type extends Array < infer ArrayType >
468+ ? [ number , ...NestedPaths < ArrayType > ]
469+ : Type extends ReadonlyArray < infer ArrayType >
470+ ? [ number , ...NestedPaths < ArrayType > ]
471+ : // eslint-disable-next-line @typescript-eslint/ban-types
472+ Type extends object
473+ ? {
474+ [ Key in Extract < keyof Type , string > ] : [ Key , ...NestedPaths < Type [ Key ] > ] ;
475+ } [ Extract < keyof Type , string > ]
476+ : [ ] ;
0 commit comments