import { RTargetPtr, RObjectTree, RObject } from './robj';
import { RObjImpl } from './robj';
import { ChannelMain } from './chan/channel';
/** Obtain a union of the keys corresponding to methods of a given class T
 */
declare type Methods<T> = {
    [P in keyof T]: T[P] extends (...args: any) => any ? P : never;
}[keyof T];
/** Distributive conditional type for RProxy
 *
 * Distributes RProxy over any RObjImpls in the given union type U.
 */
declare type DistProxy<U> = U extends RObjImpl ? RProxy<U> : U extends RObjectTree<RObjImpl> ? RObjectTree<RObject> : U;
/** Convert an RObjImpl property type to a corresponding RProxy property type
 *
 * RObjImpl types are converted into RProxy type, then wrapped in a Promise.
 *
 * Function signatures are mapped so that arguments with RObjImpl type instead
 * take RProxy<RObjImpl> type. Other function arguments remain as they are.
 * The function return type is also converted to a corresponding type
 * using RProxify recursively.
 *
 * Any other types are wrapped in a Promise.
 */
declare type RProxify<T> = T extends Array<any> ? Promise<DistProxy<T[0]>[]> : T extends (...args: infer U) => any ? (...args: {
    [V in keyof U]: DistProxy<U[V]>;
}) => RProxify<ReturnType<T>> : Promise<DistProxy<T>>;
/** Create an RProxy type based on an RObjImpl type parameter
 *
 * RProxy is intended to be used in place of RObjImpl on the main thread.
 * An RProxy has the same instance methods as the given RObjImpl parameter,
 * with the following differences:
 *   - Method arguments take RProxy rather than RObjImpl
 *   - Where an RObjImpl would be returned, an RProxy is returned instead
 *   - All return types are wrapped in a Promise
 *
 * If required, the proxy target can be accessed directly through the _target
 * property.
 */
export declare type RProxy<T extends RObjImpl> = {
    [P in Methods<T>]: RProxify<T[P]>;
} & {
    _target: RTargetPtr;
    [Symbol.asyncIterator](): AsyncGenerator<RProxy<RObjImpl>, void, unknown>;
};
export declare function newRProxy(chan: ChannelMain, target: RTargetPtr): RProxy<RObjImpl>;
export {};
