import type { AbstractModelClass } from "../modelShared/BaseModelShared";
import { idProp, ModelProps, ModelPropsToCreationData, ModelPropsToData, ModelPropsToSetter } from "../modelShared/prop";
import type { AnyModel, BaseModel, BaseModelKeys, ModelIdPropertyName } from "./BaseModel";
export declare type _ComposedCreationData<SuperModel, TProps extends ModelProps> = SuperModel extends BaseModel<any, infer CD, any> ? ModelPropsToCreationData<TProps> & CD : ModelPropsToCreationData<TProps>;
export declare type _ModelId<SuperModel, TProps extends ModelProps> = SuperModel extends AnyModel ? ModelIdPropertyName<SuperModel> : ExtractModelIdProp<TProps> & string;
export interface _Model<SuperModel, TProps extends ModelProps> {
    new (data: _ComposedCreationData<SuperModel, TProps>): SuperModel & BaseModel<ModelPropsToData<TProps>, ModelPropsToCreationData<TProps>, _ModelId<SuperModel, TProps>> & Omit<ModelPropsToData<TProps>, BaseModelKeys> & ModelPropsToSetter<TProps>;
}
/**
 * @ignore
 * Ensures that a $modelId property is present if no idProp is provided.
 */
export declare type AddModelIdPropIfNeeded<TProps extends ModelProps> = ExtractModelIdProp<TProps> extends never ? TProps & {
    $modelId: typeof idProp;
} : TProps;
/**
 * Extract the model id property from the model props.
 */
export declare type ExtractModelIdProp<TProps extends ModelProps> = {
    [K in keyof TProps]: TProps[K]["$isId"] extends true ? K : never;
}[keyof TProps];
/**
 * Base abstract class for models that extends another model.
 *
 * @typeparam TProps New model properties type.
 * @typeparam TModel Model type.
 * @param genFn Function that returns the base model and model properties.
 * @param modelOptions Model options.
 * @returns
 */
export declare function ExtendedModel<TProps extends ModelProps, TModel extends AnyModel, A extends []>(genFn: (...args: A) => {
    baseModel: AbstractModelClass<TModel>;
    props: TProps;
}, modelOptions?: ModelOptions): _Model<TModel, TProps>;
/**
 * Base abstract class for models that extends another model.
 *
 * @typeparam TProps New model properties type.
 * @typeparam TModel Model type.
 * @param baseModel Base model type.
 * @param modelProps Model properties.
 * @param modelOptions Model options.
 * @returns
 */
export declare function ExtendedModel<TProps extends ModelProps, TModel extends AnyModel>(baseModel: AbstractModelClass<TModel>, modelProps: TProps, modelOptions?: ModelOptions): _Model<TModel, TProps>;
/**
 * Base abstract class for models.
 *
 * Never override the constructor, use `onInit` or `onAttachedToRootStore` instead.
 *
 * @typeparam TProps Model properties type.
 * @param fnModelProps Function that generates model properties.
 * @param modelOptions Model options.
 */
export declare function Model<TProps extends ModelProps, A extends []>(fnModelProps: (...args: A) => TProps, modelOptions?: ModelOptions): _Model<unknown, AddModelIdPropIfNeeded<TProps>>;
/**
 * Base abstract class for models.
 *
 * Never override the constructor, use `onInit` or `onAttachedToRootStore` instead.
 *
 * @typeparam TProps Model properties type.
 * @param modelProps Model properties.
 * @param modelOptions Model options.
 */
export declare function Model<TProps extends ModelProps>(modelProps: TProps, modelOptions?: ModelOptions): _Model<unknown, AddModelIdPropIfNeeded<TProps>>;
/**
 * Model options.
 */
export interface ModelOptions {
    /**
     * A value type will be cloned automatically when being attached to a new tree.
     * The default is `false`.
     */
    valueType?: boolean;
}
