import { PreferenceService } from './preference-service';
import { IJSONSchema } from '../json-schema';
import { MaybePromise } from '../types';
import { Event } from '../event';
import { Disposable } from '../disposable';
/**
 * It is worth explaining the type for `PreferenceChangeEvent`:
 *
 * // Given T:
 * type T = { a: string, b: number }
 *
 * // We construct a new type such as:
 * type U = {
 *     a: {
 *         preferenceName: 'a'
 *         newValue: string
 *         oldValue?: string
 *     }
 *     b: {
 *        preferenceName: 'b'
 *        newValue: number
 *        oldValue?: number
 *     }
 * }
 *
 * // Then we get the union of all values of U by selecting by `keyof T`:
 * type V = U[keyof T]
 *
 * // Implementation:
 * type PreferenceChangeEvent<T> = {
 *     // Create a mapping where each key is a key from T,
 *     // -? normalizes optional typings to avoid getting
 *     // `undefined` as part of the final union:
 *     [K in keyof T]-?: {
 *         // In this object, K will take the value of each
 *         // independent key from T:
 *         preferenceName: K
 *         newValue: T[K]
 *         oldValue?: T[K]
 *     // Finally we create the union by doing so:
 *     }[keyof T]
 * }
 */
/**
 * Union of all possible key/value pairs for a type `T`
 */
export type PreferenceChangeEvent<T> = {
    affects(resourceUri?: string, overrideIdentifier?: string): boolean;
} & {
    [K in keyof T]-?: {
        readonly preferenceName: K;
    };
}[keyof T];
export interface PreferenceEventEmitter<T> {
    readonly onPreferenceChanged: Event<PreferenceChangeEvent<T>>;
    readonly ready: Promise<void>;
}
/**
 * Generic interface to declare a typesafe get function based on the given
 * configuration type.
 *
 * ### Illustration
 *
 * ```ts
 * interface PreferenceConfiguration {
 *  'myext.enabled': boolean,
 * }
 * const enabled : boolean = prefs.get('myext.enabled'); // valid
 * const debug : string = prefs.get('myext.enabled'); // invalid
 * prefs.get('foobar'); // invalid
 * ```
 */
export interface PreferenceRetrieval<T> {
    get<K extends keyof T>(preferenceName: K | {
        preferenceName: K;
        overrideIdentifier?: string;
    }, defaultValue?: T[K], resourceUri?: string): T[K];
}
/**
 * Typesafe schema-based preferences utility based on the {@link PreferenceService}.
 * Can be used to get preferences as well as listen to preference changes.
 *
 * See {@link createPreferenceProxy} on how to instantiate preference proxies.
 *
 * ### Example usage
 *
 * ```ts
 * preferences.onPreferenceChanged(({ preferenceName, newValue }) => { ... });
 * const enabled = preferences['myext.enabled'];
 * ```
 */
export type PreferenceProxy<T> = Readonly<T> & Disposable & PreferenceEventEmitter<T> & PreferenceRetrieval<T>;
export declare const PreferenceProxyOptions: unique symbol;
/**
 * Proxy configuration parameters.
 */
export interface PreferenceProxyOptions {
    /**
     * Prefix which is transparently added to all preference identifiers.
     */
    prefix?: string;
    /**
     * The default resourceUri to use if none was specified when calling "set" or "get".
     */
    resourceUri?: string;
    /**
     * The overrideIdentifier to use with the underlying preferenceService.
     * Useful to potentially override existing values while keeping both values in store.
     *
     * For example to store different editor settings, e.g. "[markdown].editor.autoIndent",
     * "[json].editor.autoIndent" and "editor.autoIndent"
     */
    overrideIdentifier?: string;
    /**
     * Indicates whether '.' in schema properties shall be interpreted as regular names (flat),
     * as declaring nested objects (deep) or both. Default is flat.
     *
     * When 'deep' or 'both' is given, nested preference proxies can be retrieved.
     */
    style?: 'flat' | 'deep' | 'both';
    /**
     * Indicates whether the proxy should be disposable. Proxies that are shared between multiple callers should not be disposable.
     */
    isDisposable?: boolean;
}
/**
 * Creates a preference proxy for typesafe preference handling.
 *
 * @param preferences the underlying preference service to use for preference handling.
 * @param promisedSchema the JSON Schema which describes which preferences are available including types and descriptions. Can be a promise.
 * @param options configuration options.
 *
 * @returns the created preference proxy.
 *
 * ### Usage
 *
 *  1. Create JSON Schema specifying your preferences
 *  2. Create Configuration type based on the JSON Schema
 *  3. Bind the return value of `createPreferenceProxy` to make your preferences available wherever needed.
 *
 * See {@link CorePreferences} for an example.
 *
 * Note that if `schema` is a Promise, most actions will be no-ops until the promise is resolved.
 *
 * @deprecated @since 1.23.0 use `PreferenceProxyFactory` instead.
 */
export declare function createPreferenceProxy<T>(preferences: PreferenceService, promisedSchema: MaybePromise<IJSONSchema>, options?: PreferenceProxyOptions): PreferenceProxy<T>;
//# sourceMappingURL=preference-proxy.d.ts.map