import { IObjectChange, IObjectWillChange } from "mobx";
import { ComplexType, IComplexType, IType } from "../type";
import { TypeFlags } from "../type-flags";
import { IStateTreeNode, IJsonPatch, Node } from "../../core";
import { IContext, IValidationResult } from "../type-checker";
export declare type ObjectTypeConfig = {
    name?: string;
    properties?: {
        [K: string]: IType<any, any>;
    };
    initializers?: ReadonlyArray<((instance: any) => any)>;
    preProcessor?: (snapshot: any) => any;
};
export declare class ObjectType<S, T> extends ComplexType<S, T> implements IModelType<S, T> {
    readonly flags: TypeFlags;
    readonly initializers: ((instance: any) => any)[];
    readonly properties: {
        [K: string]: IType<any, any>;
    };
    private preProcessor;
    private readonly propertiesNames;
    constructor(opts: ObjectTypeConfig);
    extend(opts: ObjectTypeConfig): ObjectType<any, any>;
    actions<A extends {
        [name: string]: Function;
    }>(fn: (self: T) => A): IModelType<S, T & A>;
    named(name: string): IModelType<S, T>;
    props<SP, TP>(properties: {
        [K in keyof TP]: IType<any, TP[K]>;
    } & {
        [K in keyof SP]: IType<SP[K], any>;
    }): IModelType<S & SP, T & TP>;
    views<V extends Object>(fn: (self: T) => V): IModelType<S, T & V>;
    preProcessSnapshot(preProcessor: (snapshot: any) => S): IModelType<S, T>;
    instantiate(parent: Node | null, subpath: string, environment: any, snapshot: any): Node;
    createNewInstance: () => Object;
    finalizeNewInstance: (node: Node, snapshot: any) => void;
    willChange(change: IObjectWillChange): IObjectWillChange | null;
    didChange: (change: IObjectChange) => void;
    getChildren(node: Node): Node[];
    getChildNode(node: Node, key: string): Node;
    getValue(node: Node): any;
    getSnapshot(node: Node): any;
    applyPatchLocally(node: Node, subpath: string, patch: IJsonPatch): void;
    applySnapshot(node: Node, snapshot: any): void;
    applySnapshotPreProcessor(snapshot: any): any;
    getChildType(key: string): IType<any, any>;
    isValidSnapshot(value: any, context: IContext): IValidationResult;
    private forAllProps(fn);
    describe(): string;
    getDefaultSnapshot(): any;
    removeChild(node: Node, subpath: string): void;
}
export interface IModelType<S, T> extends IComplexType<S, T & IStateTreeNode> {
    named(newName: string): IModelType<S, T>;
    props<SP, TP>(props: {
        [K in keyof TP]: IType<any, TP[K]> | TP[K];
    } & {
        [K in keyof SP]: IType<SP[K], any> | SP[K];
    }): IModelType<S & Snapshot<SP>, T & TP>;
    views<V extends Object>(fn: (self: T & IStateTreeNode) => V): IModelType<S, T & V>;
    actions<A extends {
        [name: string]: Function;
    }>(fn: (self: T & IStateTreeNode) => A): IModelType<S, T & A>;
    preProcessSnapshot(fn: (snapshot: any) => S): IModelType<S, T>;
}
export declare type IModelProperties<T> = {
    [K in keyof T]: IType<any, T[K]> | T[K];
};
export declare type IModelVolatileState<T> = {
    [K in keyof T]: ((self?: any) => T[K]) | T[K];
};
export declare type Snapshot<T> = {
    [K in keyof T]?: Snapshot<T[K]> | any;
};
export declare function model<T = {}>(name: string, properties?: IModelProperties<T>): IModelType<Snapshot<T>, T>;
export declare function model<T = {}>(properties?: IModelProperties<T>): IModelType<Snapshot<T>, T>;
export declare function compose<T1, S1, T2, S2, T3, S3>(t1: IModelType<T1, S1>, t2: IModelType<T2, S2>, t3?: IModelType<T3, S3>): IModelType<T1 & T2 & T3, S1 & S2 & S3>;
export declare function compose<T1, S1, A1, T2, S2, A2, T3, S3, A3>(name: string, t1: IModelType<T1, S1>, t2: IModelType<T2, S2>, t3?: IModelType<T3, S3>): IModelType<T1 & T2 & T3, S1 & S2 & S3>;
