import { dataTypeSymbol } from "../modelShared/BaseModelShared";
import type { TypeCheckError } from "../typeChecking/TypeCheckError";
/**
 * Base abstract class for data models. Use `DataModel` instead when extending.
 *
 * Never override the constructor, use `onLazyInit` instead.
 *
 * @typeparam Data Props data type.
 */
export declare abstract class BaseDataModel<Data extends {
    [k: string]: any;
}> {
    [dataTypeSymbol]: Data;
    /**
     * Called after the instance is created when there's the first call to `fn(M, data)`.
     */
    protected onLazyInit?(): void;
    /**
     * Data part of the model, which is observable and will be serialized in snapshots.
     * Use it if one of the data properties matches one of the model properties/functions.
     * This also allows access to the backed values of transformed properties.
     */
    readonly $: Data;
    /**
     * Performs a type check over the model instance.
     * For this to work a data type has to be declared as part of the model properties.
     *
     * @returns A `TypeCheckError` or `null` if there is no error.
     */
    typeCheck(): TypeCheckError | null;
    /**
     * Creates an instance of a data model.
     */
    constructor(data: Data);
    toString(options?: {
        withData?: boolean;
    }): string;
}
/**
 * @ignore
 */
export declare type BaseDataModelKeys = keyof AnyDataModel | "onLazyInit";
/**
 * Any kind of data model instance.
 */
export interface AnyDataModel extends BaseDataModel<any> {
}
/**
 * A data model class declaration, made of a base model and the model interface.
 */
export declare type DataModelClassDeclaration<BaseModelClass, ModelInterface> = BaseModelClass & {
    (...args: any[]): ModelInterface;
};
