UNPKG

valia

Version:

A runtime data validator in TypeScript with advanced type inference, built-in validation functions, and seamless integration for server and client environments.

96 lines (83 loc) 2.77 kB
import type { RecordSetableCriteria } from "../record/types"; import type { SetableCriteriaTemplate, SetableCriteriaMap, FlowTypesTemplate, SetableCriteria, MountedCriteria, GuardedCriteria, FormatNames } from "../types"; export type SetableStruct<T extends FormatNames = FormatNames> = { [key: string | symbol]: SetableCriteria<T> | SetableStruct<T>; }; export interface StructSetableCriteria< T extends FormatNames = FormatNames > extends SetableCriteriaTemplate<"struct"> { struct: SetableStruct<T>; optional?: (string | symbol)[] | boolean; additional?: SetableCriteriaMap<T>['record'] | boolean; } type MountedStruct<T extends SetableStruct> = { [K in keyof T]: T[K] extends SetableCriteria ? MountedCriteria<T[K]> : T[K] extends SetableStruct ? MountedCriteria<{ type: "struct", struct: T[K] }> : never; }; export interface StructMountedCriteria<T extends StructSetableCriteria> { struct: MountedStruct<T['struct']>; optional: unknown extends T['optional'] ? false : StructSetableCriteria['optional'] extends T['optional'] ? (string | symbol)[] | boolean : T['optional']; additional: unknown extends T['additional'] ? false : StructSetableCriteria['additional'] extends T['additional'] ? MountedCriteria<RecordSetableCriteria> | boolean : T['additional'] extends RecordSetableCriteria ? MountedCriteria<T['additional']> : T['additional'] acceptedKeys: Set<string | symbol>; requiredKeys: Set<string | symbol>; } type DynamicProperties<U extends RecordSetableCriteria | boolean | undefined> = [U] extends [RecordSetableCriteria] ? GuardedCriteria<U> : [U] extends [false] ? {} : { [key: string | symbol]: unknown; }; type OptionalizeKeys<T, U extends (string | symbol)[] | boolean | undefined> = [U] extends [(string | symbol)[]] ? { [K in keyof T as K extends U[number] ? K : never]+?: T[K]; } & { [K in keyof T as K extends U[number] ? never : K]-?: T[K]; } : [U] extends [false] ? { [P in keyof T]-?: T[P]; } : { [P in keyof T]+?: T[P]; }; type StaticProperties<T extends StructSetableCriteria> = { -readonly [K in keyof OptionalizeKeys<T['struct'], T['optional']>]: T['struct'][K] extends SetableCriteria ? GuardedCriteria<T['struct'][K]> : never; } type StructGuardedCriteria<T extends StructSetableCriteria> = DynamicProperties<T['additional']> extends infer U ? StaticProperties<T> extends infer V ? { [K in keyof (U & V)]: K extends keyof V ? V[K] : K extends keyof U ? U[K] : never; } : never : never; export interface StructFlowTypes<T extends StructSetableCriteria> extends FlowTypesTemplate< StructMountedCriteria<T>, StructGuardedCriteria<T> > {}