@corentinth/chisels
Version:
Collection of utilities for JavaScript and TypeScript, lightweight and tree-shakable.
188 lines (180 loc) • 4.86 kB
TypeScript
/**
* 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 ? keyof Args extends never ? () => ReturnType<Functions[K]> : {} extends Args ? (args?: Args) => ReturnType<Functions[K]> : (args: Args) => ReturnType<Functions[K]> : never; };
/**
* This function takes a function that returns a value and returns a new function that caches the result of the first call. Basically a argument-less memoization.
*
* @example
* ```typescript
* const getCwd = memoizeOnce(() => process.cwd());
*
* // process.cwd() is only called once
* console.log(getCwd());
* console.log(getCwd());
* ```
*/
declare function memoizeOnce<T>(value: () => T): () => T;
/**
* 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, memoizeOnce, safely, safelySync };
export type { DeepPartial, Dictionary, Expand, PartialBy, Subtract };