@@ -68,8 +68,8 @@ export type WithoutId<TSchema> = Omit<TSchema, '_id'>;
6868export type Filter < TSchema > =
6969 | Partial < TSchema >
7070 | ( {
71- [ Property in Join < NestedPaths < WithId < TSchema > , true > , '.' > ] ?: Condition <
72- PropertyType < WithId < TSchema > , Property , true >
71+ [ Property in Join < NestedPaths < WithId < TSchema > > , '.' > ] ?: Condition <
72+ PropertyType < WithId < TSchema > , Property >
7373 > ;
7474 } & RootFilterOperators < WithId < TSchema > > ) ;
7575
@@ -261,9 +261,19 @@ export type OnlyFieldsOfType<TSchema, FieldType = any, AssignableType = FieldTyp
261261> ;
262262
263263/** @public */
264- export type MatchKeysAndValues < TSchema > = Readonly < {
265- [ Property in Join < NestedPaths < TSchema , false > , '.' > ] ?: PropertyType < TSchema , Property , false > ;
266- } > ;
264+ export type MatchKeysAndValues < TSchema > = Readonly <
265+ {
266+ [ Property in Join < NestedPaths < TSchema > , '.' > ] ?: PropertyType < TSchema , Property > ;
267+ } & {
268+ [ Property in `${NestedPathsOfType < TSchema , any [ ] > } .$${`[${string } ]` | '' } `] ?: ArrayElement <
269+ PropertyType < TSchema , Property extends `${infer Key } .$${string } ` ? Key : never >
270+ > ;
271+ } & {
272+ [ Property in `${NestedPathsOfType < TSchema , Record < string , any > [ ] > } .$${
273+ | `[${string } ]`
274+ | '' } .${string } `] ?: any ; // Could be further narrowed
275+ }
276+ > ;
267277
268278/** @public */
269279export type AddToSetOperators < Type > = {
@@ -464,83 +474,75 @@ export type Join<T extends unknown[], D extends string> = T extends []
464474 : string ;
465475
466476/** @public */
467- export type PropertyType <
468- Type ,
469- Property extends string ,
470- AllowToSkipArrayIndex extends boolean
471- > = Type extends unknown
472- ? string extends Property
473- ? Type extends Map < string , infer MapType >
477+ export type PropertyType < Type , Property extends string > = string extends Property
478+ ? unknown
479+ : Property extends keyof Type
480+ ? Type [ Property ]
481+ : Property extends `${number } `
482+ ? Type extends ReadonlyArray < infer ArrayType >
483+ ? ArrayType
484+ : unknown
485+ : Property extends `${infer Key } .${infer Rest } `
486+ ? Key extends `${number } `
487+ ? Type extends ReadonlyArray < infer ArrayType >
488+ ? PropertyType < ArrayType , Rest >
489+ : unknown
490+ : Key extends keyof Type
491+ ? Type [ Key ] extends Map < string , infer MapType >
474492 ? MapType
475- : never
476- :
477- | ( AllowToSkipArrayIndex extends false
478- ? never
479- : Type extends ReadonlyArray < infer ArrayType >
480- ? PropertyType < ArrayType , Property , AllowToSkipArrayIndex >
481- : never )
482- | ( Property extends keyof Type
483- ? Type [ Property ]
484- : Property extends `${number | `$${'' | `[${string } ]`} `} `
485- ? Type extends ReadonlyArray < infer ArrayType >
486- ? ArrayType
487- : never
488- : Property extends `${infer Key } .${infer Rest } `
489- ? Key extends `${number | `$${'' | `[${string } ]`} `} `
490- ? Type extends ReadonlyArray < infer ArrayType >
491- ? PropertyType < ArrayType , Rest , AllowToSkipArrayIndex >
492- : never
493- : Key extends keyof Type
494- ? PropertyType < Type [ Key ] , Rest , AllowToSkipArrayIndex >
495- : never
496- : never )
497- : never ;
493+ : PropertyType < Type [ Key ] , Rest >
494+ : unknown
495+ : unknown ;
498496
499497/**
500498 * @public
501499 * returns tuple of strings (keys to be joined on '.') that represent every path into a schema
502500 * https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
503501 */
504- export type NestedPaths < Type , AllowToSkipArrayIndex extends boolean > = Type extends unknown
505- ? Type extends
506- | string
507- | number
508- | boolean
509- | Date
510- | RegExp
511- | Buffer
512- | Uint8Array
513- | ( ( ...args : any [ ] ) => any )
514- | { _bsontype : string }
515- ? never
516- : Type extends ReadonlyArray < infer ArrayType >
517- ? [
518- ...(
519- | ( AllowToSkipArrayIndex extends true ? [ ] : never )
520- | [ number | `$${'' | `[${string } ]`} `]
521- ) ,
522- ...( [ ] | NestedPaths < ArrayType , AllowToSkipArrayIndex > )
523- ]
524- : Type extends Map < string , any >
525- ? [ string ]
526- : Type extends object
527- ? {
528- [ Key in Extract < keyof Type , string > ] : Type [ Key ] extends Type // type of value extends the parent
529- ? [ Key ]
530- : // for a recursive union type, the child will never extend the parent type.
531- // but the parent will still extend the child
532- Type extends Type [ Key ]
533- ? [ Key ]
534- : Type [ Key ] extends ReadonlyArray < infer ArrayType > // handling recursive types with arrays
535- ? Type extends ArrayType // is the type of the parent the same as the type of the array?
536- ? [ Key ] // yes, it's a recursive array type
537- : // for unions, the child type extends the parent
538- ArrayType extends Type
539- ? [ Key ] // we have a recursive array union
540- : // child is an array, but it's not a recursive array
541- [ Key , ...( [ ] | NestedPaths < Type [ Key ] , AllowToSkipArrayIndex > ) ]
542- : // child is not structured the same as the parent
543- [ Key , ...( [ ] | NestedPaths < Type [ Key ] , AllowToSkipArrayIndex > ) ] ;
544- } [ Extract < keyof Type , string > ]
545- : never
546- : never ;
502+ export type NestedPaths < Type > = Type extends
503+ | string
504+ | number
505+ | boolean
506+ | Date
507+ | RegExp
508+ | Buffer
509+ | Uint8Array
510+ | ( ( ...args : any [ ] ) => any )
511+ | { _bsontype : string }
512+ ? [ ]
513+ : Type extends ReadonlyArray < infer ArrayType >
514+ ? [ ] | [ number , ...NestedPaths < ArrayType > ]
515+ : Type extends Map < string , any >
516+ ? [ string ]
517+ : Type extends object
518+ ? {
519+ [ Key in Extract < keyof Type , string > ] : Type [ Key ] extends Type // type of value extends the parent
520+ ? [ Key ]
521+ : // for a recursive union type, the child will never extend the parent type.
522+ // but the parent will still extend the child
523+ Type extends Type [ Key ]
524+ ? [ Key ]
525+ : Type [ Key ] extends ReadonlyArray < infer ArrayType > // handling recursive types with arrays
526+ ? Type extends ArrayType // is the type of the parent the same as the type of the array?
527+ ? [ Key ] // yes, it's a recursive array type
528+ : // for unions, the child type extends the parent
529+ ArrayType extends Type
530+ ? [ Key ] // we have a recursive array union
531+ : // child is an array, but it's not a recursive array
532+ [ Key , ...NestedPaths < Type [ Key ] > ]
533+ : // child is not structured the same as the parent
534+ [ Key , ...NestedPaths < Type [ Key ] > ] | [ Key ] ;
535+ } [ Extract < keyof Type , string > ]
536+ : [ ] ;
537+
538+ /**
539+ * @public
540+ * returns keys (strings) for every path into a schema with a value of type
541+ * https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
542+ */
543+ export type NestedPathsOfType < TSchema , Type > = KeysOfAType <
544+ {
545+ [ Property in Join < NestedPaths < TSchema > , '.' > ] : PropertyType < TSchema , Property > ;
546+ } ,
547+ Type
548+ > ;
0 commit comments