import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from "../annotations.js"; import type { Schema } from "../Schema.js"; import type { ArraySchema } from "./custom/ArraySchema.js"; import type { CollectionSchema } from "./custom/CollectionSchema.js"; import type { MapSchema } from "./custom/MapSchema.js"; import type { SetSchema } from "./custom/SetSchema.js"; export type Constructor = new (...args: any[]) => T; type PrimitiveStringToType = T extends "string" ? string : T extends "number" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "float32" | "float64" ? number : T extends "boolean" ? boolean : T; export interface Collection { [Symbol.iterator](): IterableIterator; forEach(callback: Function): void; entries(): IterableIterator<[K, V]>; } export type InferValueType = T extends "string" ? string : T extends "number" ? number : T extends "int8" ? number : T extends "uint8" ? number : T extends "int16" ? number : T extends "uint16" ? number : T extends "int32" ? number : T extends "uint32" ? number : T extends "int64" ? number : T extends "uint64" ? number : T extends "float32" ? number : T extends "float64" ? number : T extends "boolean" ? boolean : T extends { type: infer ChildType extends PrimitiveType; } ? InferValueType : T extends { type: infer ChildType extends Constructor; } ? InstanceType : T extends { type: Array; } ? (ChildType extends Record ? ChildType[keyof ChildType][] : ChildType[]) : T extends { type: { map: infer ChildType; }; } ? (ChildType extends Record ? MapSchema : MapSchema) : T extends { type: { set: infer ChildType; }; } ? (ChildType extends Record ? SetSchema : SetSchema) : T extends { type: { collection: infer ChildType; }; } ? (ChildType extends Record ? CollectionSchema : CollectionSchema) : T extends { type: infer ChildType; } ? (ChildType extends Record ? ChildType[keyof ChildType] : ChildType) : T extends Array ? ArraySchema> : T extends Array ? (ChildType extends Record ? ArraySchema : ArraySchema>) : T extends { array: infer ChildType extends Constructor; } ? ArraySchema> : T extends { array: infer ChildType; } ? (ChildType extends Record ? ArraySchema : ArraySchema>) : T extends { map: infer ChildType extends Constructor; } ? MapSchema> : T extends { map: infer ChildType; } ? (ChildType extends Record ? MapSchema : MapSchema>) : T extends { set: infer ChildType extends Constructor; } ? SetSchema> : T extends { set: infer ChildType extends RawPrimitiveType; } ? SetSchema> : T extends { set: infer ChildType; } ? (ChildType extends Record ? SetSchema : SetSchema) : T extends { collection: infer ChildType extends Constructor; } ? CollectionSchema> : T extends { collection: infer ChildType extends RawPrimitiveType; } ? CollectionSchema> : T extends { collection: infer ChildType; } ? (ChildType extends Record ? CollectionSchema : CollectionSchema) : T extends Constructor ? InstanceType : T extends Record ? T[keyof T] : T extends PrimitiveType ? T : never; export type InferSchemaInstanceType = { [K in keyof T]: T[K] extends (...args: any[]) => any ? (T[K] extends new (...args: any[]) => any ? InferValueType : T[K]) : InferValueType; } & Schema; export type NonFunctionProps = Omit; export type NonFunctionPropNames = { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]; export type NonFunctionNonPrimitivePropNames = { [K in keyof T]: T[K] extends Function ? never : T[K] extends number | string | boolean ? never : K; }[keyof T]; type ToJSONValue = U extends Schema ? ToJSON : PrimitiveStringToType; export type ToJSON = { [K in keyof T as T[K] extends Function ? never : K]: T[K] extends MapSchema ? Record> : T[K] extends Map ? Record> : T[K] extends ArraySchema ? ToJSONValue[] : T[K] extends SetSchema ? ToJSONValue[] : T[K] extends CollectionSchema ? ToJSONValue[] : T[K] extends Schema ? ToJSON : T[K]; }; export type IsNever = [T] extends [never] ? true : false; /** * Type helper for .assign() method - allows assigning values in a flexible way * - Primitives can be assigned directly * - Schema instances can be assigned from plain objects or Schema instances * - Collections can be assigned from their JSON representations */ export type AssignableProps = { [K in NonFunctionPropNames]?: T[K] extends MapSchema ? MapSchema | Record) : U> : T[K] extends ArraySchema ? ArraySchema | (U extends Schema ? (U | AssignableProps)[] : U[]) : T[K] extends SetSchema ? SetSchema | Set | (U extends Schema ? (U | AssignableProps)[] : U[]) : T[K] extends CollectionSchema ? CollectionSchema | (U extends Schema ? (U | AssignableProps)[] : U[]) : T[K] extends Schema ? T[K] | AssignableProps : T[K]; }; export {};