diff --git a/src/mongo_types.ts b/src/mongo_types.ts index e68ff4fe86b..ed10f48b167 100644 --- a/src/mongo_types.ts +++ b/src/mongo_types.ts @@ -269,7 +269,7 @@ export type MatchKeysAndValues = Readonly< PropertyType >; } & { - [Property in `${NestedPathsOfType[]>}.$${ + [Property in `${NestedPathsOfType[]>}.$${ | `[${string}]` | ''}.${string}`]?: any; // Could be further narrowed } @@ -478,14 +478,18 @@ export type PropertyType = string extends Propert ? unknown : Property extends keyof Type ? Type[Property] - : Property extends `${number}` + : Property extends `${infer NumberProperty extends number}` ? Type extends ReadonlyArray ? ArrayType + : NumberProperty extends keyof Type + ? Type[NumberProperty] : unknown : Property extends `${infer Key}.${infer Rest}` - ? Key extends `${number}` + ? Key extends `${infer NumberKey extends number}` ? Type extends ReadonlyArray ? PropertyType + : NumberKey extends keyof Type + ? PropertyType : unknown : Key extends keyof Type ? Type[Key] extends Map @@ -516,23 +520,23 @@ export type NestedPaths = Type extends ? [string] : Type extends object ? { - [Key in Extract]: Type[Key] extends Type // type of value extends the parent - ? [Key] - : // for a recursive union type, the child will never extend the parent type. - // but the parent will still extend the child - Type extends Type[Key] - ? [Key] - : Type[Key] extends ReadonlyArray // handling recursive types with arrays - ? Type extends ArrayType // is the type of the parent the same as the type of the array? - ? [Key] // yes, it's a recursive array type - : // for unions, the child type extends the parent - ArrayType extends Type - ? [Key] // we have a recursive array union - : // child is an array, but it's not a recursive array - [Key, ...NestedPaths] - : // child is not structured the same as the parent - [Key, ...NestedPaths] | [Key]; - }[Extract] + [Key in Extract]: Type[Key] extends infer Value + ? Value extends any // distribute union types + ? // the type of the parent is the same as the type of the value (see https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650) + (() => T extends Type ? 1 : 2) extends () => T extends Value ? 1 : 2 + ? [Key] // the object value type is recursive + : Type[Key] extends ReadonlyArray // handling recursive types with arrays + ? Type extends ArrayType // is the type of the parent the same as the type of the array? + ? [Key] // yes, it's a recursive array type + : // for unions, the child type extends the parent + ArrayType extends Type + ? [Key] // we have a recursive array union + : // child is an array, but it's not a recursive array + [Key, ...NestedPaths] + : [Key] | [Key, ...NestedPaths] // not recursive + : never + : never; + }[Extract] : []; /**