export type OptionalExceptFor<T, TRequired extends keyof T = keyof T> = Partial<Pick<T, Exclude<keyof T, TRequired>>> & Required<Pick<T, TRequired>>;
export type StringMap<T> = {
    [key in keyof T]: string;
};
export type Await<T> = T extends PromiseLike<infer U> ? U : T;
export type ValueOf<T> = T[keyof T];
export type DeepPartial<T> = T extends object ? {
    [P in keyof T]?: DeepPartial<T[P]>;
} : T;
/**
 A union type that represents a value that can be directly awaited or a promise that will eventually resolve to a value of type T.
 */
export type Awaitable<T> = Awaited<T> | Promise<Awaited<T>>;
/**
 * This is a helper type that takes a type T and returns a type that is the same as T, but with all
 * properties that are functions removed.
 *
 * @example
 * ```ts
 * type Foo = {
 *     bar: string;
 *     qux: () => void;
 * }
 *
 * type FooWithoutFunctions = RemoveFunctions<Foo>;
 *
 * // FooWithoutFunctions is equivalent to:
 * type FooWithoutFunctions = {
 *     bar: string;
 * }
 * ```
 */
export type RemoveFunctions<T> = Pick<T, {
    [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T]>;
type MissingKeys<T, U> = Exclude<keyof T, U>;
/**
 * A utility function that checks if the provided keys are valid for the given type T.
 * The key thing it does is to ensure that all keys in T are present in the array, typescript can check for extra keys but not missing keys.
 * While it is a function, it is really just a type check. The function is needed to encapsulate the type logic.
 * It will throw a type error if any of the keys are not present in T.
 *
 * @example
 * ```ts
 * type Foo = {
 *     bar: string;
 *     qux?: string;
 * };
 *
 * const fooChecker = makeKeyChecker<Foo>();
 * const allFooKeys = fooChecker(['bar', 'qux']); // Valid
 * fooChecker(['bar']); // Error: Missing keys: qux
 * fooChecker(['qux']); // Error: Missing keys: bar
 * fooChecker(['bar', 'qux', 'baz']); // 'baz' is not assignable to type keyof Foo;
 * ```
 */
export declare const makeKeyChecker: <T extends object>() => <K extends (keyof T)[]>(arr: K & (MissingKeys<T, K[number]> extends never ? unknown : `Error: Missing keys: ${string & MissingKeys<T, K[number]>}`)) => K;
export {};
