From a2255ff836b383582b8baa4ff6140240cdd76d9a Mon Sep 17 00:00:00 2001 From: Max Nowack Date: Fri, 11 Oct 2024 21:42:43 +0200 Subject: [PATCH] feat: enable type checking for query selectors --- packages/signaldb/src/types/Selector.ts | 40 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/signaldb/src/types/Selector.ts b/packages/signaldb/src/types/Selector.ts index 161880f9..5523e25e 100644 --- a/packages/signaldb/src/types/Selector.ts +++ b/packages/signaldb/src/types/Selector.ts @@ -1,4 +1,4 @@ -// borrowed from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/meteor/mongo.d.ts +// original from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/meteor/mongo.d.ts export interface FieldExpression { $eq?: T | undefined, @@ -35,11 +35,45 @@ export interface FieldExpression { $bitsAnySet?: any, } +// Utility type to check if a type is an array or object. +type IsObject = T extends object ? (T extends Array ? false : true) : false + +// Recursive type to generate dot-notation keys +type DotNotationKeys = { + [K in keyof T & (string | number)]: + T[K] extends Array + // If it's an array, include both the index and the $ wildcard + ? `${K}` | `${K}.$` | `${K}.${DotNotationKeys}` + // If it's an object, recurse into it + : IsObject extends true + ? `${K}` | `${K}.${DotNotationKeys}` + : `${K}` // Base case: Just return the key +}[keyof T & (string | number)] + +type Split = + S extends `${infer Head}${Delimiter}${infer Tail}` + ? [Head, ...Split] + : [S] + +type GetTypeByParts = + Parts extends [infer Head, ...infer Tail] + ? Head extends keyof T + ? GetTypeByParts> + : Head extends '$' + ? T extends Array + ? GetTypeByParts> + : never + : never + : T + +type Get = + GetTypeByParts> + type Flatten = T extends any[] ? T[0] : T type FlatQuery = { - [P in keyof T]?: Flatten | RegExp | FieldExpression> -} & Record + [P in DotNotationKeys]?: Flatten> | RegExp | FieldExpression>> +} type Query = FlatQuery & { $or?: Query[] | undefined, $and?: Query[] | undefined,