/**
 * Formats a number of bytes into a human-readable string.
 *
 * @example
 * ```typescript
 * const formatted = formatBytes({ bytes: 4194304 });
 *
 * console.log(formatted); // 4 MiB
 * ```
 */
declare function formatBytes({ bytes, decimals, base, units, }: {
    bytes: number;
    decimals?: number;
    base?: 1000 | 1024;
    units?: string[];
}): string;

/**
 *  Casts an unknown value to an Error.
 *
 *  @example
 *  ```typescript
 *  try {
 *      // ...
 *  } catch (rawError) {
 *    const error = castError(rawError);
 *
 *    // Do something with a proper Error instance
 *  }
 *  ```
 */
declare function castError(error: unknown): Error;

/**
 * Make some properties of T optional
 *
 * @example
 * ```typescript
 * type User = {
 *   id: number;
 *   name: string;
 *   email: string;
 * };
 *
 * type PartialUser = PartialBy<User, 'email' | 'name'>;
 *
 * const user: PartialUser = { id: 1 };
 * ```
 */
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
/**
 * Flatten an object type for better IDE support
 */
type Expand<T> = T extends infer O ? {
    [K in keyof O]: O[K];
} : never;
/**
 * Record<string, T> alias
 *
 * @example
 * ```typescript
 * const dictionary: Dictionary<number> = {
 *   a: 1,
 *   b: 2,
 * };
 * ```
 */
type Dictionary<T = unknown> = Record<string, T>;
/**
 * Make all properties of T optional recursively
 */
type DeepPartial<T> = T extends object ? {
    [P in keyof T]?: DeepPartial<T[P]>;
} : T;
/**
 * Exclude properties of T that are in U
 *
 * @example
 * ```typescript
 * type User = {
 *   id: number;
 *   name: string;
 *   email: string;
 * };
 *
 * type WithId = {
 *   id: number;
 * }
 *
 * type UserWithoutId = Subtract<User, WithId>;
 * ```
 */
type Subtract<T, U> = Pick<T, Exclude<keyof T, keyof U>>;

/**
 *  Injects arguments into a set of functions. Useful for DI of repositories, services, etc.
 *
 *  @example
 *  ```typescript
 *  const functions = {
 *   getUser: ({ userId, db }) => db.users.find({ id: userId }),
 *   removeUser: ({ userId, db }) => db.users.remove({ id: userId }),
 *  };
 *
 *  const { getUser, removeUser } = injectArguments(functions, { db });
 *
 *  getUser({ userId: 1 });
 *  removeUser({ userId: 1 });
 * ```
 */
declare function injectArguments<Functions extends Dictionary<(args: any) => any>, InjectedArgs>(functions: Functions, injectedArgs: InjectedArgs): { [K in keyof Functions]: Expand<Subtract<Parameters<Functions[K]>[0], InjectedArgs>> extends infer Args ? {} extends Args ? () => ReturnType<Functions[K]> : (args: Args) => ReturnType<Functions[K]> : never; };

/**
 * Safely executes an async function or promise and return a tuple with the result and an error if any.
 *
 * @example
 * ```typescript
 * const [result, error] = await safely(myFunction);
 *
 * if (error) {
 *  console.error(error);
 * }
 *
 * console.log(result);
 * ```
 */
declare function safely<T>(fn: (() => Promise<T> | T) | Promise<T>): Promise<[T, null] | [null, Error]>;
/**
 * Safely executes a function and return a tuple with the result and an error if any.
 *
 * @example
 * ```typescript
 * const [result, error] = safelySync(myFunction);
 *
 * if (error) {
 *  console.error(error);
 * }
 *
 * console.log(result);
 * ```
 */
declare function safelySync<T>(fn: () => T): [T, null] | [null, Error];

/**
 * Join URL parts and trim slashes.
 *
 * @example
 * ```typescript
 * const url = joinUrlPaths('/part1/', '/part2/', 'part3', 'part4/');
 *
 * console.log(url); // 'part1/part2/part3/part4'
 * ```
 */
declare function joinUrlPaths(...parts: (string | null | undefined)[]): string;
/**
 * Functional wrapper around URL constructor to build an URL string from a base URL and optional path, query params and hash.
 *
 * @example
 * ```typescript
 * const url = buildUrl({ baseUrl: 'https://example.com', path: 'foo', queryParams: { a: '1', b: '2' }, hash: 'hash' });
 *
 * console.log(url); // 'https://example.com/foo?a=1&b=2#hash'
 * ```
 */
declare function buildUrl({ path: pathOrPaths, baseUrl, queryParams, hash, }: {
    path?: string | string[];
    baseUrl: string;
    queryParams?: Record<string, string> | URLSearchParams;
    hash?: string;
}): string;

export { buildUrl, castError, formatBytes, injectArguments, joinUrlPaths, safely, safelySync };
export type { DeepPartial, Dictionary, Expand, PartialBy, Subtract };
