import { type AnyObject, type DefaultValueProvider, type TargetModel, type Model, type ModelConverter, type ModelMetadata } from './Model.js';
import type { ObjectModel } from './models.js';
declare const $model: unique symbol;
export type Flags = {
    named: boolean;
};
export declare class CoreModelBuilder<V, EX extends AnyObject = AnyObject, F extends Flags = {
    named: false;
}> {
    protected readonly [$model]: Model<V, EX>;
    constructor(base: Model, defaultValueProvider?: (model: Model<V, EX>) => V);
    meta(value: ModelMetadata): this;
    define<const DK extends symbol, const DV>(key: DK, value: TypedPropertyDescriptor<DV>): CoreModelBuilder<V, {
        readonly [key in keyof EX | DK]: key extends DK ? DV : key extends keyof EX ? EX[key] : never;
    }, F>;
    defaultValueProvider(defaultValueProvider: DefaultValueProvider<V, EX>): this;
    name(name: string): CoreModelBuilder<V, EX, {
        named: true;
    }>;
    build(this: F['named'] extends true ? this : never): AnyObject extends EX ? Model<V> : Model<V, EX>;
}
export declare class ObjectModelBuilder<V extends AnyObject, CV extends AnyObject = AnyObject, EX extends AnyObject = AnyObject, F extends Flags = {
    named: false;
}> extends CoreModelBuilder<V, {
    readonly [K in keyof EX]: EX[K] extends ModelConverter ? TargetModel<EX[K], ObjectModel<V, EX>> : EX[K];
}, F> {
    constructor(base: Model);
    object<NV extends V>(this: F['named'] extends false ? this : never, name: string): ObjectModelBuilder<NV, CV, EX, {
        named: true;
    }>;
    ['define']: <const DK extends symbol, DV>(key: DK, value: TypedPropertyDescriptor<DV>) => ObjectModelBuilder<V, CV, {
        readonly [key in keyof EX | DK]: key extends DK ? DV : key extends keyof EX ? EX[key] : never;
    }, F>;
    ['meta']: (value: ModelMetadata) => this;
    property<const PK extends string & keyof V, const M extends Model<V[PK]>>(key: PK, model: M): ObjectModelBuilder<V, {
        readonly [key in keyof CV | PK]: key extends PK ? V[PK] : key extends keyof CV ? CV[key] : never;
    }, {
        readonly [key in keyof EX | PK]: key extends PK ? M : key extends keyof EX ? EX[key] : never;
    }, F>;
    property<const PK extends string & keyof V, const MC extends ModelConverter>(key: PK, model: MC): ObjectModelBuilder<V, {
        readonly [key in keyof CV | PK]: key extends PK ? V[PK] : key extends keyof CV ? CV[key] : never;
    }, {
        readonly [key in keyof EX | PK]: key extends PK ? MC : key extends keyof EX ? EX[key] : never;
    }, F>;
    build: (this: F['named'] extends true ? (CV extends V ? this : never) : never) => ObjectModel<V, EX>;
}
export {};
