import { FieldProcessor } from '@ephox/boulder';
import { Optional } from '@ephox/katamari';
import { SimpleOrSketchSpec } from '../api/component/SpecTypes';
import { CompositeSketchDetail } from '../api/ui/Sketcher';
type DeepPartial<T> = {
    [P in keyof T]?: Partial<T[P]>;
};
export type PartType<S, T = PartTypeAdt<S>> = (p: S) => T;
export interface BasePartDetail<D extends CompositeSketchDetail, PS> {
    defaults: OverrideHandler<D, PS>;
    factory: {
        sketch: (detail: PS & {
            uid: string;
        }, ...rest: any[]) => any;
    };
    name: string;
    overrides: OverrideHandler<D, PS>;
    pname: string;
    schema: FieldProcessor[];
}
export interface PartDetail<D extends CompositeSketchDetail, PS> extends BasePartDetail<D, PS> {
    factory: {
        sketch: (detail: PS & {
            uid: string;
        }) => any;
    };
}
export interface ExternalPartDetail<D extends CompositeSketchDetail, PS> extends BasePartDetail<D, PS> {
    factory: {
        sketch: (detail: PS & {
            uid: string;
        }, partSpec: PS) => any;
    };
}
export interface GroupPartDetail<D extends CompositeSketchDetail, PS> extends PartDetail<D, PS> {
    unit: string;
}
export interface PartSpec<D extends CompositeSketchDetail, PS> extends Partial<PartDetail<D, PS>> {
    name: string;
}
export interface ExternalPartSpec<D extends CompositeSketchDetail, PS> extends Partial<ExternalPartDetail<D, PS>> {
}
export interface GroupPartSpec<D extends CompositeSketchDetail, PS> extends Partial<GroupPartDetail<D, PS>> {
    name: string;
    unit: string;
}
export type OverrideHandler<D, PS> = (detail: D, spec: PS, partValidated?: Record<string, any>) => DeepPartial<PS>;
export interface PartTypeAdt<S = BasePartDetail<any, any>> {
    fold: <T>(required: PartType<S, T>, external: PartType<S, T>, optional: PartType<S, T>, group: PartType<S, T>) => T;
    match: <T>(branches: {
        required: PartType<S, T>;
        external: PartType<S, T>;
        optional: PartType<S, T>;
        group: PartType<S, T>;
    }) => T;
    log: (label: string) => void;
}
declare const asNamedPart: <T>(part: PartTypeAdt<T>) => Optional<T>;
declare const name: <T extends {
    name: string;
}>(part: PartTypeAdt<T>) => string;
declare const asCommon: <T>(part: PartTypeAdt<T>) => T;
declare const required: (<D extends CompositeSketchDetail, PS = SimpleOrSketchSpec>(p: PartSpec<D, PS>) => PartTypeAdt<PartDetail<D, PS>>);
declare const external: (<D extends CompositeSketchDetail, PS = SimpleOrSketchSpec>(p: ExternalPartSpec<D, PS>) => PartTypeAdt<ExternalPartDetail<D, PS>>);
declare const optional: (<D extends CompositeSketchDetail, PS = SimpleOrSketchSpec>(p: PartSpec<D, PS>) => PartTypeAdt<PartDetail<D, PS>>);
declare const group: (<D extends CompositeSketchDetail, PS = SimpleOrSketchSpec>(p: GroupPartSpec<D, PS>) => PartTypeAdt<GroupPartDetail<D, PS>>);
declare const original: () => string;
export { required, external, optional, group, asNamedPart, name, asCommon, original };
//# sourceMappingURL=PartType.d.ts.map