import type { EmptyObject } from 'type-fest';
export interface JvmTypeRef {
    jvmType: string;
    genericArguments?: JvmTypeRef[];
}
export type AnnotationValue = AnnotationValue[] | JvmTypeRef | boolean | number | string | undefined;
export interface Annotation {
    jvmType: string;
    arguments: Record<string, AnnotationValue>;
}
export interface ModelMetadata {
    jvmType?: string;
    annotations?: Annotation[];
}
export type Target<T = unknown> = Readonly<{
    model?: Model<T>;
    value: T;
}>;
export declare const nothing: unique symbol;
export declare enum Enum {
}
export type AnyObject = Readonly<Record<never, never>>;
export declare const $key: unique symbol;
export declare const $name: unique symbol;
export declare const $owner: unique symbol;
export declare const $meta: unique symbol;
export declare const $optional: unique symbol;
export declare const $defaultValue: unique symbol;
export declare const $enum: unique symbol;
export declare const $members: unique symbol;
export declare const $itemModel: unique symbol;
export type Value<M extends Model> = M extends Model<infer T> ? T : never;
export type Extensions<M extends Model> = M extends Model<unknown, infer EX> ? EX : EmptyObject;
export type References<M extends Model> = M extends Model<unknown, AnyObject, infer R> ? R : never;
export type Model<V = unknown, EX extends AnyObject = EmptyObject, R extends keyof any = never> = EX & Readonly<{
    [P in R]: Model<V, EX, R>;
}> & Readonly<{
    [$key]: keyof any;
    [$name]: string;
    [$owner]: Model | Target;
    [$meta]?: ModelMetadata;
    [$optional]: boolean;
    [$defaultValue]: V;
    [Symbol.toStringTag]: string;
    [Symbol.hasInstance](value: any): value is Model<V, EX, R>;
    toString(): string;
}>;
export type DefaultValueProvider<V, EX extends AnyObject = EmptyObject, R extends keyof any = never> = (model: Model<V, EX, R>) => V;
export declare const Model: Model;
