toss / es-toolkit

A modern JavaScript utility library that's 2-3 times faster and up to 97% smaller—a major upgrade to lodash.
https://es-toolkit.slash.page
Other
6.13k stars 248 forks source link

Suggest to enhance `clone()` function. #196

Open samchon opened 1 month ago

samchon commented 1 month ago

Current clone() function considers only those native classes.

However, there are much more native classes in the JavaScript, especially about binary handling.

So, I think that the clone() function should consider them.

Also, current clone() function is returning the same T type with its parameter, but it is not correct.

The returned type must be casted, because non-native classes are converted to primitve object type.

To solve this problem, the clone() function needs to return Shallowed<T> type like below.

type Shallowed<T> = Equal<T, ShallowMain<T>> extends true ? T : ShallowMain<T>
type ShallowMain<T> = T extends [never]
  ? never
  : T extends object
  ? T extends 
    | Array<any> | Set<any> | Map<any, any> | Date | RegExp | Date
    | Uint8Array
    | Uint8ClampedArray
    | Uint16Array
    | Uint32Array
    | BigUint64Array
    | Int8Array
    | Int16Array
    | Int32Array
    | BigInt64Array
    | Float32Array
    | Float64Array
    | ArrayBuffer
    | SharedArrayBuffer
    | DataView
    | Blob
    | File
  ? T
  : {
    [P in keyof T]: T[P] extends Function ? never : T[P];
  }
  : T;
type Equal<X, Y> = X extends Y ? (Y extends X ? true : false) : false;

Related PR: https://github.com/toss/es-toolkit/pull/155

raon0211 commented 1 month ago

As you mentioned, our clone function should handle most JavaScript native objects. One thing that comes to my mind is that it will hurt bundle size, but accuracy is more important...

ahaoboy commented 1 month ago

Maybe you should use https://developer.mozilla.org/en-US/docs/Web/API/structuredClone