UNPKG

@stryke/helpers

Version:

A package containing miscellaneous helper functions that are used across many different Storm Software projects.

67 lines (66 loc) 3.67 kB
export type Resolved<T> = Equal<T, ResolvedMain<T>> extends true ? T : ResolvedMain<T>; type Equal<X, Y> = X extends Y ? (Y extends X ? true : false) : false; type ResolvedMain<T> = T extends [never] ? never : ValueOf<T> extends boolean | number | bigint | string ? ValueOf<T> : T extends (...args: any[]) => any ? never : T extends object ? ResolvedObject<T> : ValueOf<T>; type ResolvedObject<T extends object> = T extends (infer U)[] ? IsTuple<T> extends true ? ResolvedTuple<T> : ResolvedMain<U>[] : T extends Set<infer U> ? Set<ResolvedMain<U>> : T extends Map<infer K, infer V> ? Map<ResolvedMain<K>, ResolvedMain<V>> : T extends WeakSet<any> | WeakMap<any, any> ? never : T extends Date | Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | BigUint64Array | Int8Array | Int16Array | Int32Array | BigInt64Array | Float32Array | Float64Array | ArrayBuffer | SharedArrayBuffer | DataView | Blob | File ? T : { [P in keyof T]: ResolvedMain<T[P]>; }; type ResolvedTuple<T extends readonly any[]> = T extends [] ? [] : T extends [infer F] ? [ResolvedMain<F>] : T extends [infer F, ...infer Rest extends readonly any[]] ? [ResolvedMain<F>, ...ResolvedTuple<Rest>] : T extends [(infer F)?] ? [ResolvedMain<F>?] : T extends [(infer F)?, ...infer Rest extends readonly any[]] ? [ResolvedMain<F>?, ...ResolvedTuple<Rest>] : []; type IsTuple<T extends readonly any[] | { length: number; }> = [T] extends [ never ] ? false : T extends readonly any[] ? number extends T["length"] ? false : true : false; type ValueOf<Instance> = IsValueOf<Instance, boolean> extends true ? boolean : IsValueOf<Instance, number> extends true ? number : IsValueOf<Instance, string> extends true ? string : Instance; type IsValueOf<Instance, O extends ValueOfInterface<any>> = Instance extends O ? O extends ValueOfInterface<infer Primitive> ? Instance extends Primitive ? false : true : false : false; interface ValueOfInterface<T> { valueOf: () => T; } /** * Creates a deep clone of the given object. * * @remarks * This function creates a deep clone of the given object, including nested objects and arrays. The resulting output will be of type `Resolved<T>`, which is a type that resolves to the most specific type possible for the given input type `T`. **If you are just looking for a way to copy an object deeply, use {@link deepCopy} instead.** * * @example * ```typescript * // Clone a primitive values * const num = 29; * const clonedNum = clone(num); * console.log(clonedNum); // 29 * console.log(clonedNum === num) ; // true * * // Clone an array * const arr = [1, 2, 3]; * const clonedArr = clone(arr); * console.log(clonedArr); // [1, 2, 3] * console.log(clonedArr === arr); // false * * // Clone an array with nested objects * const arr = [1, { a: 1 }, [1, 2, 3]]; * const clonedArr = clone(arr); * arr[1].a = 2; * console.log(arr); // [2, { a: 2 }, [1, 2, 3]] * console.log(clonedArr); // [1, { a: 1 }, [1, 2, 3]] * console.log(clonedArr === arr); // false * * // Clone an object * const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] }; * const clonedObj = clone(obj); * console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] } * console.log(clonedObj === obj); // false * * * // Clone an object with nested objects * const obj = { a: 1, b: { c: 1 } }; * const clonedObj = clone(obj); * obj.b.c = 2; * console.log(obj); // { a: 1, b: { c: 2 } } * console.log(clonedObj); // { a: 1, b: { c: 1 } } * console.log(clonedObj === obj); // false * ``` * * @param obj - The object to clone. * @returns A deep clone of the given object. */ export declare function deepClone<T>(obj: T): Resolved<T>; export {};