@augment-vir/common
Version:
A collection of augments, helpers types, functions, and classes for any JavaScript environment.
47 lines (46 loc) • 3.04 kB
TypeScript
import { type AnyObject, type RequiredKeysOf } from '@augment-vir/core';
import { type IsAny, type IsNever, type OptionalKeysOf, type Primitive, type UnionToIntersection } from 'type-fest';
import { type TsRecurse, type TsRecursionStart, type TsRecursionTracker, type TsTooMuchRecursion } from '../type/type-recursion.js';
/** All types that won't be recursed into when defining a {@link SelectionSet}. */
type SelectionTypesToPreserve = Primitive | RegExp | Promise<any>;
/**
* A generic selection set without specific keys. Useful for type parameter baselines.
*
* @category Selection
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export type GenericSelectionSet = {
[Key in PropertyKey]: unknown;
};
type MakeKeysOptional<Full extends AnyObject, T extends AnyObject> = IsNever<Extract<OptionalKeysOf<Full>, keyof T>> extends true ? {
[Key in keyof T]: T[Key];
} : IsNever<Extract<RequiredKeysOf<Full>, keyof T>> extends true ? {
[Key in keyof T]?: T[Key];
} : /** Optional and required keys. */ {
[Key in Extract<RequiredKeysOf<Full>, keyof T>]: T[Key];
} & {
[Key in Extract<OptionalKeysOf<Full>, keyof T>]?: T[Key];
};
/**
* Performs a SQL-like nested selection on an object, extracting the selected values. This produces
* the output type for `selectFrom`.
*
* @category Selection
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export type SelectFrom<Full extends Readonly<AnyObject>, Selection extends SelectionSet<Full>, Depth extends TsRecursionTracker = TsRecursionStart> = Depth extends TsTooMuchRecursion ? ['Error: recursive object depth is too deep.'] : Full extends ReadonlyArray<infer Element extends any> ? (SelectFrom<Extract<Element, AnyObject>, Selection, TsRecurse<Depth>> | Exclude<Element, AnyObject>)[] : MakeKeysOptional<Full, {
-readonly [Key in keyof Selection as Selection[Key] extends false ? never : Key extends keyof Full ? Key : never]: (Selection[Key] extends GenericSelectionSet ? SelectFrom<NonNullable<Extract<Full[Key], AnyObject>>, Selection[Key], TsRecurse<Depth>> : Full[Key]) | Exclude<Full[Key], AnyObject>;
}>;
/**
* Defines a selection set for a given object type. This is used in {@link SelectFrom}.
*
* @category Selection
* @category Package : @augment-vir/common
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
*/
export type SelectionSet<Full extends Readonly<AnyObject>, Depth extends TsRecursionTracker = TsRecursionStart> = IsAny<Full> extends true ? any : Depth extends TsTooMuchRecursion ? boolean : Full extends ReadonlyArray<infer FullChild extends AnyObject> ? SelectionSet<FullChild, TsRecurse<Depth>> : Partial<{
[Key in keyof Full]: IsNever<Exclude<Full[Key], SelectionTypesToPreserve>> extends true ? boolean : UnionToIntersection<SelectionSet<NonNullable<Required<Full>[Key]>, TsRecurse<Depth>>> | boolean;
}>;
export {};