type Primitive = undefined | null | string | number | boolean | bigint | symbol;
type Builtin = Primitive | Date | Error | RegExp | ((...args: any[]) => unknown);

export type DeepPartial<T> = T extends Builtin
	? T
	: T extends []
	  ? []
	  : T extends [infer U, ...infer R]
	    ? [DeepPartial<U>, ...DeepPartial<R>]
	    : T extends Array<infer U>
	      ? Array<DeepPartial<U>>
	      : T extends ReadonlyArray<infer U>
	        ? ReadonlyArray<DeepPartial<U>>
	        : T extends Map<infer K, infer V>
	          ? Map<DeepPartial<K>, DeepPartial<V>>
	          : T extends ReadonlyMap<infer K, infer V>
	            ? ReadonlyMap<DeepPartial<K>, DeepPartial<V>>
	            : T extends WeakMap<infer K, infer V>
	              ? WeakMap<DeepPartial<K>, DeepPartial<V>>
	              : T extends Set<infer U>
	                ? Set<DeepPartial<U>>
	                : T extends ReadonlySet<infer U>
	                  ? ReadonlySet<DeepPartial<U>>
	                  : T extends WeakSet<infer U>
	                    ? WeakSet<DeepPartial<U>>
	                    : T extends Promise<infer U>
	                      ? Promise<DeepPartial<U>>
	                      : T extends Record<any, any>
	                        ? { [K in keyof T]?: DeepPartial<T[K]> }
	                        : Partial<T>;

export type JsonValue = null | string | number | boolean | JsonValue[] | { [key: string]: JsonValue };

export type GenericString<T> = T extends string ? string : T;

export type Plural<T extends string> = `${T}s`;

export type UnknownObject = Record<string | number | symbol, unknown>;

export type PromiseCallback = () => void | Promise<void>;

export type Prettify<T> = {
	[K in keyof T]: T[K];
} & unknown;
