import '../../assert/js/assert.js';
import '../../globals.js';
import KeysMatching from '../../phet-core/js/types/KeysMatching.js';
import { PropertyOptions } from './Property.js';
import ReadOnlyProperty from './ReadOnlyProperty.js';
import TProperty from './TProperty.js';
import TReadOnlyProperty from './TReadOnlyProperty.js';
export type TNullableProperty<T> = TReadOnlyProperty<T | null> | TReadOnlyProperty<T>;
type SelfOptions<ThisValueType, InnerValueType, OuterValueType> = {
    bidirectional?: boolean;
    defaultValue?: InnerValueType;
    derive?: ((outerValue: OuterValueType) => TReadOnlyProperty<InnerValueType>) | KeysMatching<OuterValueType, TReadOnlyProperty<InnerValueType>>;
    map?: ((innerValue: InnerValueType) => ThisValueType) | KeysMatching<InnerValueType, ThisValueType>;
    inverseMap?: ((value: ThisValueType) => InnerValueType) | KeysMatching<ThisValueType, InnerValueType>;
};
export type DynamicPropertyOptions<ThisValueType, InnerValueType, OuterValueType> = SelfOptions<ThisValueType, InnerValueType, OuterValueType> & PropertyOptions<ThisValueType>;
export default class DynamicProperty<ThisValueType, InnerValueType, OuterValueType> extends ReadOnlyProperty<ThisValueType> implements TProperty<ThisValueType> {
    private isExternallyChanging;
    private readonly defaultValue;
    protected readonly derive: (u: OuterValueType) => TReadOnlyProperty<InnerValueType>;
    protected readonly map: (v: InnerValueType) => ThisValueType;
    protected readonly inverseMap: (t: ThisValueType) => InnerValueType;
    protected readonly bidirectional: boolean;
    private readonly valuePropertyProperty;
    private readonly propertyPropertyListener;
    private readonly propertyListener;
    /**
     * @param valuePropertyProperty - If the value is null, it is considered disconnected.
     * @param [providedOptions] - options
     */
    constructor(valuePropertyProperty: TNullableProperty<OuterValueType> | TReadOnlyProperty<OuterValueType>, providedOptions?: DynamicPropertyOptions<ThisValueType, InnerValueType, OuterValueType>);
    /**
     * Listener added to the active inner Property.
     *
     * @param value - Should be either our defaultValue (if valuePropertyProperty.value is null), or
     *                derive( valuePropertyProperty.value ).value otherwise.
     * @param oldValue - Ignored for our purposes, but is the 2nd parameter for Property listeners.
     * @param innerProperty
     */
    private onPropertyPropertyChange;
    /**
     * Listener added to the outer Property.
     *
     * @param newPropertyValue - If derive is not provided then it should be a {Property.<*>|null}
     * @param oldPropertyValue - If derive is not provided then it should be a {Property.<*>|null}.
     *                                              We additionally handle the initial link() case where this is
     *                                              undefined.
     */
    private onPropertyChange;
    /**
     * Listener added to ourself when we are bidirectional
     */
    private onSelfChange;
    /**
     * Disposes this Property
     */
    dispose(): void;
    /**
     * Resets the current property (if it's a Property instead of a TinyProperty)
     */
    reset(): void;
    /**
     * Prevent setting this Property manually if it is not marked as bidirectional.
     */
    set(value: ThisValueType): void;
    /**
     * Overridden to make public
     */
    get value(): ThisValueType;
    /**
     * Overridden to make public
     * We ran performance tests on Chrome, and determined that calling super.value = newValue is statistically significantly
     * slower at the p = 0.10 level( looping over 10,000 value calls). Therefore, we prefer this optimization.
     */
    set value(value: ThisValueType);
    /**
     * Returns true if this Property value can be set externally, by set() or .value =
     */
    isSettable(): boolean;
}
export {};
//# sourceMappingURL=DynamicProperty.d.ts.map