import { Ensure, Evaluate } from '../helpers/index';
import { type TSchema } from '../schema/index';
import { type TArray } from '../array/index';
import { type TAwaited } from '../awaited/index';
import { type TAsyncIterator } from '../async-iterator/index';
import { TComputed } from '../computed/index';
import { type TConstructor } from '../constructor/index';
import { type TIndex, type TIndexPropertyKeys } from '../indexed/index';
import { TEnum, type TEnumRecord } from '../enum/index';
import { type TFunction } from '../function/index';
import { type TIntersect, type TIntersectEvaluated } from '../intersect/index';
import { type TIterator } from '../iterator/index';
import { type TKeyOf } from '../keyof/index';
import { type TObject, type TProperties } from '../object/index';
import { type TOmit } from '../omit/index';
import { type TOptional } from '../optional/index';
import { type TPick } from '../pick/index';
import { type TNever } from '../never/index';
import { TPartial } from '../partial/index';
import { type TReadonly } from '../readonly/index';
import { type TRecordOrObject, type TRecord } from '../record/index';
import { type TRef } from '../ref/index';
import { type TRequired } from '../required/index';
import { type TTransform } from '../transform/index';
import { type TTuple } from '../tuple/index';
import { type TUnion, type TUnionEvaluated } from '../union/index';
type TDereferenceParameters<ModuleProperties extends TProperties, Types extends TSchema[], Result extends TSchema[] = []> = (Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TRef<infer Key extends string> ? TDereferenceParameters<ModuleProperties, Right, [...Result, TDereference<ModuleProperties, Key>]> : TDereferenceParameters<ModuleProperties, Right, [...Result, TFromType<ModuleProperties, Left>]> : Result);
type TDereference<ModuleProperties extends TProperties, Ref extends string, Result extends TSchema = (Ref extends keyof ModuleProperties ? ModuleProperties[Ref] extends TRef<infer Ref2 extends string> ? TDereference<ModuleProperties, Ref2> : TFromType<ModuleProperties, ModuleProperties[Ref]> : TNever)> = Result;
type TFromAwaited<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema] ? TAwaited<T0> : never);
type TFromIndex<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] ? TIndex<T0, TIndexPropertyKeys<T1>> extends infer Result extends TSchema ? Result : never : never);
type TFromKeyOf<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema] ? TKeyOf<T0> : never);
type TFromPartial<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema] ? TPartial<T0> : never);
type TFromOmit<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] ? TOmit<T0, T1> : never);
type TFromPick<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] ? TPick<T0, T1> : never);
type TFromRequired<Parameters extends TSchema[]> = (Parameters extends [infer T0 extends TSchema] ? TRequired<T0> : never);
type TFromComputed<ModuleProperties extends TProperties, Target extends string, Parameters extends TSchema[], Dereferenced extends TSchema[] = TDereferenceParameters<ModuleProperties, Parameters>> = (Target extends 'Awaited' ? TFromAwaited<Dereferenced> : Target extends 'Index' ? TFromIndex<Dereferenced> : Target extends 'KeyOf' ? TFromKeyOf<Dereferenced> : Target extends 'Partial' ? TFromPartial<Dereferenced> : Target extends 'Omit' ? TFromOmit<Dereferenced> : Target extends 'Pick' ? TFromPick<Dereferenced> : Target extends 'Required' ? TFromRequired<Dereferenced> : TNever);
type TFromArray<ModuleProperties extends TProperties, Type extends TSchema> = (Ensure<TArray<TFromType<ModuleProperties, Type>>>);
type TFromAsyncIterator<ModuleProperties extends TProperties, Type extends TSchema> = (TAsyncIterator<TFromType<ModuleProperties, Type>>);
type TFromConstructor<ModuleProperties extends TProperties, Parameters extends TSchema[], InstanceType extends TSchema> = (TConstructor<TFromTypes<ModuleProperties, Parameters>, TFromType<ModuleProperties, InstanceType>>);
type TFromFunction<ModuleProperties extends TProperties, Parameters extends TSchema[], ReturnType extends TSchema> = Ensure<Ensure<TFunction<TFromTypes<ModuleProperties, Parameters>, TFromType<ModuleProperties, ReturnType>>>>;
type TFromIntersect<ModuleProperties extends TProperties, Types extends TSchema[]> = (Ensure<TIntersectEvaluated<TFromTypes<ModuleProperties, Types>>>);
type TFromIterator<ModuleProperties extends TProperties, Type extends TSchema> = (TIterator<TFromType<ModuleProperties, Type>>);
type TFromObject<ModuleProperties extends TProperties, Properties extends TProperties> = Ensure<TObject<Evaluate<{
    [Key in keyof Properties]: TFromType<ModuleProperties, Properties[Key]>;
}>>>;
type TFromRecord<ModuleProperties extends TProperties, Key extends TSchema, Value extends TSchema, Result extends TSchema = TRecordOrObject<Key, TFromType<ModuleProperties, Value>>> = Result;
type TFromTransform<ModuleProperties extends TProperties, Input extends TSchema, Output extends unknown, Result extends TSchema = Input extends TRef<infer Key extends string> ? TTransform<TDereference<ModuleProperties, Key>, Output> : TTransform<Input, Output>> = Result;
type TFromTuple<ModuleProperties extends TProperties, Types extends TSchema[]> = (Ensure<TTuple<TFromTypes<ModuleProperties, Types>>>);
type TFromUnion<ModuleProperties extends TProperties, Types extends TSchema[]> = (Ensure<TUnionEvaluated<TFromTypes<ModuleProperties, Types>>>);
type TFromTypes<ModuleProperties extends TProperties, Types extends TSchema[], Result extends TSchema[] = []> = (Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromTypes<ModuleProperties, Right, [...Result, TFromType<ModuleProperties, Left>]> : Result);
export type TFromType<ModuleProperties extends TProperties, Type extends TSchema> = (Type extends TOptional<infer Type extends TSchema> ? TOptional<TFromType<ModuleProperties, Type>> : Type extends TReadonly<infer Type extends TSchema> ? TReadonly<TFromType<ModuleProperties, Type>> : Type extends TTransform<infer Input extends TSchema, infer Output extends unknown> ? TFromTransform<ModuleProperties, Input, Output> : Type extends TArray<infer Type extends TSchema> ? TFromArray<ModuleProperties, Type> : Type extends TAsyncIterator<infer Type extends TSchema> ? TFromAsyncIterator<ModuleProperties, Type> : Type extends TComputed<infer Target extends string, infer Parameters extends TSchema[]> ? TFromComputed<ModuleProperties, Target, Parameters> : Type extends TConstructor<infer Parameters extends TSchema[], infer InstanceType extends TSchema> ? TFromConstructor<ModuleProperties, Parameters, InstanceType> : Type extends TFunction<infer Parameters extends TSchema[], infer ReturnType extends TSchema> ? TFromFunction<ModuleProperties, Parameters, ReturnType> : Type extends TIntersect<infer Types extends TSchema[]> ? TFromIntersect<ModuleProperties, Types> : Type extends TIterator<infer Type extends TSchema> ? TFromIterator<ModuleProperties, Type> : Type extends TObject<infer Properties extends TProperties> ? TFromObject<ModuleProperties, Properties> : Type extends TRecord<infer Key extends TSchema, infer Value extends TSchema> ? TFromRecord<ModuleProperties, Key, Value> : Type extends TTuple<infer Types extends TSchema[]> ? TFromTuple<ModuleProperties, Types> : Type extends TEnum<infer _ extends TEnumRecord> ? Type : Type extends TUnion<infer Types extends TSchema[]> ? TFromUnion<ModuleProperties, Types> : Type);
export declare function FromType<ModuleProperties extends TProperties, Type extends TSchema>(moduleProperties: ModuleProperties, type: Type): TFromType<ModuleProperties, Type>;
export type TComputeType<ModuleProperties extends TProperties, Key extends PropertyKey> = (Key extends keyof ModuleProperties ? TFromType<ModuleProperties, ModuleProperties[Key]> : TNever);
export declare function ComputeType<ModuleProperties extends TProperties, Key extends PropertyKey>(moduleProperties: ModuleProperties, key: Key): TComputeType<ModuleProperties, Key>;
export type TComputeModuleProperties<ModuleProperties extends TProperties> = Evaluate<{
    [Key in keyof ModuleProperties]: TComputeType<ModuleProperties, Key>;
}>;
export declare function ComputeModuleProperties<ModuleProperties extends TProperties>(moduleProperties: ModuleProperties): TComputeModuleProperties<ModuleProperties>;
export {};
