es-toolkit 1.52.0-dev.2135 → 1.52.0-dev.2137

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ //#region src/types/IsAny.d.ts
2
+ /**
3
+ * Resolves to `true` when `T` is `any`, `false` otherwise.
4
+ *
5
+ * `any` is the only type that `1 & T` can turn into something `0` is
6
+ * assignable to, which is what makes it possible to tell `any` apart from
7
+ * `unknown` and from every other type.
8
+ *
9
+ * @template T - The type to check.
10
+ *
11
+ * @example
12
+ * type A = IsAny<any>; // true
13
+ * type B = IsAny<unknown>; // false
14
+ * type C = IsAny<never>; // false
15
+ */
16
+ type IsAny<T> = 0 extends 1 & T ? true : false;
17
+ //#endregion
18
+ export { IsAny };
@@ -0,0 +1,18 @@
1
+ //#region src/types/IsAny.d.ts
2
+ /**
3
+ * Resolves to `true` when `T` is `any`, `false` otherwise.
4
+ *
5
+ * `any` is the only type that `1 & T` can turn into something `0` is
6
+ * assignable to, which is what makes it possible to tell `any` apart from
7
+ * `unknown` and from every other type.
8
+ *
9
+ * @template T - The type to check.
10
+ *
11
+ * @example
12
+ * type A = IsAny<any>; // true
13
+ * type B = IsAny<unknown>; // false
14
+ * type C = IsAny<never>; // false
15
+ */
16
+ type IsAny<T> = 0 extends 1 & T ? true : false;
17
+ //#endregion
18
+ export { IsAny };
@@ -0,0 +1,20 @@
1
+ import { IsAny } from "./IsAny.mjs";
2
+
3
+ //#region src/types/IsUnknown.d.ts
4
+ /**
5
+ * Resolves to `true` when `T` is `unknown`, `false` otherwise.
6
+ *
7
+ * A plain `unknown extends T` check is also `true` for `any`, so this type
8
+ * rules `any` out first. Useful when a type-level helper should treat an
9
+ * `unknown` input differently from a concrete type.
10
+ *
11
+ * @template T - The type to check.
12
+ *
13
+ * @example
14
+ * type A = IsUnknown<unknown>; // true
15
+ * type B = IsUnknown<any>; // false
16
+ * type C = IsUnknown<string>; // false
17
+ */
18
+ type IsUnknown<T> = IsAny<T> extends true ? false : unknown extends T ? true : false;
19
+ //#endregion
20
+ export { IsUnknown };
@@ -0,0 +1,20 @@
1
+ import { IsAny } from "./IsAny.js";
2
+
3
+ //#region src/types/IsUnknown.d.ts
4
+ /**
5
+ * Resolves to `true` when `T` is `unknown`, `false` otherwise.
6
+ *
7
+ * A plain `unknown extends T` check is also `true` for `any`, so this type
8
+ * rules `any` out first. Useful when a type-level helper should treat an
9
+ * `unknown` input differently from a concrete type.
10
+ *
11
+ * @template T - The type to check.
12
+ *
13
+ * @example
14
+ * type A = IsUnknown<unknown>; // true
15
+ * type B = IsUnknown<any>; // false
16
+ * type C = IsUnknown<string>; // false
17
+ */
18
+ type IsUnknown<T> = IsAny<T> extends true ? false : unknown extends T ? true : false;
19
+ //#endregion
20
+ export { IsUnknown };
@@ -1,3 +1,7 @@
1
+ import { IsAny } from "./IsAny.mjs";
2
+ import { IsEqual } from "./IsEqual.mjs";
3
+ import { IsUnknown } from "./IsUnknown.mjs";
4
+ import { Primitive } from "./Primitive.mjs";
1
5
  import { Simplify } from "./Simplify.mjs";
2
6
 
3
7
  //#region src/types/Merge.d.ts
@@ -5,15 +9,29 @@ import { Simplify } from "./Simplify.mjs";
5
9
  * The result of deeply merging the source type `S` into the target type `T`,
6
10
  * matching what `merge(target, source)` returns at runtime.
7
11
  *
8
- * Keys present on only one side are kept as-is. When both sides have a plain
9
- * object at the same key, the merge recurses; tuples merge index by index, and
10
- * other arrays merge into an array of both element types. If the source value
11
- * can be `undefined`, the target type is kept because `merge` skips
12
- * `undefined` source values. Values that are not plain objects or arrays
13
- * (functions, `Date`, `RegExp`, `Map`, `Set`, etc.) are not merged into;
14
- * the source value replaces the target value. When an array meets a plain
15
- * object, `merge` keeps the target and assigns the source's properties onto
16
- * it, so both property sets are kept (`T & S`).
12
+ * Merging a type with itself gives back the same type, so a union such as
13
+ * `string | string[] | string[][]` stays intact instead of expanding into a
14
+ * merge of every pair of its members.
15
+ *
16
+ * Plain objects are merged key by key: keys present on only one side are
17
+ * kept, and keys present on both sides are merged the same way. A key that
18
+ * exists only on the source is kept even when the source is a subtype of
19
+ * the target.
20
+ *
21
+ * A source value that is not a plain object or an array (primitives, `Date`,
22
+ * `RegExp`, `Map`, `Set`, functions, ...) replaces the target value, so the
23
+ * source type is used.
24
+ *
25
+ * When a source array fits the target's array type, the target type is kept:
26
+ * overriding `string[] | string[][]` with `string[]` stays
27
+ * `string[] | string[][]`. If instead the target fits the source type, the
28
+ * source type is kept. Otherwise, tuples merge index by index and other
29
+ * arrays merge into an array of both element types.
30
+ *
31
+ * A source value that can be `undefined` keeps the target
32
+ * type as well, because `merge` skips `undefined` source values. When an
33
+ * array meets a plain object, `merge` keeps the target and assigns the
34
+ * source's properties onto it, so both property sets are kept (`T & S`).
17
35
  *
18
36
  * @template T - Type of the target object.
19
37
  * @template S - Type of the source object.
@@ -23,6 +41,15 @@ import { Simplify } from "./Simplify.mjs";
23
41
  * type Source = { b: { y: string; z: boolean }; c: string };
24
42
  * type Result = Merge<Target, Source>;
25
43
  * // => { a: number; b: { x: number; y: string; z: boolean }; c: string }
44
+ *
45
+ * @example
46
+ * type Options = { color: string | string[] | string[][] };
47
+ * type Same = Merge<Options, Options>;
48
+ * // => Options
49
+ * type Override = Merge<Options, { color: string[] }>;
50
+ * // => Options
51
+ * type Extra = Merge<{ a: number }, { a: number; b: string }>;
52
+ * // => { a: number; b: string }
26
53
  */
27
54
  type Merge<T, S> = undefined extends S ? T | MergeDefined<T, Exclude<S, undefined>> : MergeDefined<T, S>;
28
55
  /**
@@ -30,8 +57,17 @@ type Merge<T, S> = undefined extends S ? T | MergeDefined<T, Exclude<S, undefine
30
57
  * or an array. The source value replaces the target value instead.
31
58
  */
32
59
  type NonMergeable = ((...args: any[]) => unknown) | Date | RegExp | Error | Promise<unknown> | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | WeakMap<object, unknown> | WeakSet<object>;
33
- type MergeDefined<T, S> = S extends readonly unknown[] ? (T extends readonly unknown[] ? MergeArrays<T, S> : T extends NonMergeable ? S : T extends object ? T & S : S) : S extends NonMergeable ? S : S extends object ? (T extends readonly unknown[] ? T & S : T extends NonMergeable ? S : T extends object ? MergeRecords<T, S> : S) : S;
60
+ /**
61
+ * `true` when every member of `T` is a plain object type that `merge`
62
+ * recurses into. Primitives are excluded explicitly because an intersection
63
+ * like `string & {}` satisfies `extends object` even though it is a string at
64
+ * runtime.
65
+ */
66
+ type IsPlainRecord<T> = T extends Primitive ? false : T extends readonly unknown[] ? false : T extends NonMergeable ? false : T extends object ? true : false;
67
+ type MergeDefined<T, S> = IsEqual<T, S> extends true ? T : IsAny<T> extends true ? any : IsAny<S> extends true ? any : IsUnknown<T> extends true ? S : [T] extends [never] ? S : [S] extends [never] ? T : IsPlainRecord<T> extends true ? (IsPlainRecord<S> extends true ? MergeRecords<T, S> : MergeAssignable<T, S>) : MergeAssignable<T, S>;
68
+ type MergeAssignable<T, S> = [S] extends [Primitive | NonMergeable] ? S : [S] extends [T] ? T : [T] extends [S] ? S : MergeFallback<T, S>;
69
+ type MergeFallback<T, S> = S extends Primitive ? S : S extends readonly unknown[] ? (T extends readonly unknown[] ? MergeArrays<T, S> : T extends Primitive | NonMergeable ? S : T extends object ? T & S : S) : S extends NonMergeable ? S : S extends object ? (T extends readonly unknown[] ? T & S : T extends Primitive | NonMergeable ? S : T extends object ? MergeRecords<T, S> : S) : S;
34
70
  type MergeArrays<T extends readonly unknown[], S extends readonly unknown[]> = T extends readonly [] ? S : S extends readonly [] ? T : T extends readonly [infer TH, ...infer TR] ? S extends readonly [infer SH, ...infer SR] ? [Merge<TH, SH>, ...MergeArrays<TR, SR>] : Array<T[number] | S[number]> : Array<T[number] | S[number]>;
35
- type MergeRecords<T extends object, S extends object> = Simplify<Omit<T, keyof S> & Omit<S, keyof T> & { [K in keyof T & keyof S]: Merge<T[K], S[K]> }>;
71
+ type MergeRecords<T, S> = Simplify<Omit<T, keyof S> & Omit<S, keyof T> & { [K in keyof T & keyof S]: Merge<T[K], S[K]> }>;
36
72
  //#endregion
37
73
  export { Merge };
@@ -1,3 +1,7 @@
1
+ import { IsAny } from "./IsAny.js";
2
+ import { IsEqual } from "./IsEqual.js";
3
+ import { IsUnknown } from "./IsUnknown.js";
4
+ import { Primitive } from "./Primitive.js";
1
5
  import { Simplify } from "./Simplify.js";
2
6
 
3
7
  //#region src/types/Merge.d.ts
@@ -5,15 +9,29 @@ import { Simplify } from "./Simplify.js";
5
9
  * The result of deeply merging the source type `S` into the target type `T`,
6
10
  * matching what `merge(target, source)` returns at runtime.
7
11
  *
8
- * Keys present on only one side are kept as-is. When both sides have a plain
9
- * object at the same key, the merge recurses; tuples merge index by index, and
10
- * other arrays merge into an array of both element types. If the source value
11
- * can be `undefined`, the target type is kept because `merge` skips
12
- * `undefined` source values. Values that are not plain objects or arrays
13
- * (functions, `Date`, `RegExp`, `Map`, `Set`, etc.) are not merged into;
14
- * the source value replaces the target value. When an array meets a plain
15
- * object, `merge` keeps the target and assigns the source's properties onto
16
- * it, so both property sets are kept (`T & S`).
12
+ * Merging a type with itself gives back the same type, so a union such as
13
+ * `string | string[] | string[][]` stays intact instead of expanding into a
14
+ * merge of every pair of its members.
15
+ *
16
+ * Plain objects are merged key by key: keys present on only one side are
17
+ * kept, and keys present on both sides are merged the same way. A key that
18
+ * exists only on the source is kept even when the source is a subtype of
19
+ * the target.
20
+ *
21
+ * A source value that is not a plain object or an array (primitives, `Date`,
22
+ * `RegExp`, `Map`, `Set`, functions, ...) replaces the target value, so the
23
+ * source type is used.
24
+ *
25
+ * When a source array fits the target's array type, the target type is kept:
26
+ * overriding `string[] | string[][]` with `string[]` stays
27
+ * `string[] | string[][]`. If instead the target fits the source type, the
28
+ * source type is kept. Otherwise, tuples merge index by index and other
29
+ * arrays merge into an array of both element types.
30
+ *
31
+ * A source value that can be `undefined` keeps the target
32
+ * type as well, because `merge` skips `undefined` source values. When an
33
+ * array meets a plain object, `merge` keeps the target and assigns the
34
+ * source's properties onto it, so both property sets are kept (`T & S`).
17
35
  *
18
36
  * @template T - Type of the target object.
19
37
  * @template S - Type of the source object.
@@ -23,6 +41,15 @@ import { Simplify } from "./Simplify.js";
23
41
  * type Source = { b: { y: string; z: boolean }; c: string };
24
42
  * type Result = Merge<Target, Source>;
25
43
  * // => { a: number; b: { x: number; y: string; z: boolean }; c: string }
44
+ *
45
+ * @example
46
+ * type Options = { color: string | string[] | string[][] };
47
+ * type Same = Merge<Options, Options>;
48
+ * // => Options
49
+ * type Override = Merge<Options, { color: string[] }>;
50
+ * // => Options
51
+ * type Extra = Merge<{ a: number }, { a: number; b: string }>;
52
+ * // => { a: number; b: string }
26
53
  */
27
54
  type Merge<T, S> = undefined extends S ? T | MergeDefined<T, Exclude<S, undefined>> : MergeDefined<T, S>;
28
55
  /**
@@ -30,8 +57,17 @@ type Merge<T, S> = undefined extends S ? T | MergeDefined<T, Exclude<S, undefine
30
57
  * or an array. The source value replaces the target value instead.
31
58
  */
32
59
  type NonMergeable = ((...args: any[]) => unknown) | Date | RegExp | Error | Promise<unknown> | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | WeakMap<object, unknown> | WeakSet<object>;
33
- type MergeDefined<T, S> = S extends readonly unknown[] ? (T extends readonly unknown[] ? MergeArrays<T, S> : T extends NonMergeable ? S : T extends object ? T & S : S) : S extends NonMergeable ? S : S extends object ? (T extends readonly unknown[] ? T & S : T extends NonMergeable ? S : T extends object ? MergeRecords<T, S> : S) : S;
60
+ /**
61
+ * `true` when every member of `T` is a plain object type that `merge`
62
+ * recurses into. Primitives are excluded explicitly because an intersection
63
+ * like `string & {}` satisfies `extends object` even though it is a string at
64
+ * runtime.
65
+ */
66
+ type IsPlainRecord<T> = T extends Primitive ? false : T extends readonly unknown[] ? false : T extends NonMergeable ? false : T extends object ? true : false;
67
+ type MergeDefined<T, S> = IsEqual<T, S> extends true ? T : IsAny<T> extends true ? any : IsAny<S> extends true ? any : IsUnknown<T> extends true ? S : [T] extends [never] ? S : [S] extends [never] ? T : IsPlainRecord<T> extends true ? (IsPlainRecord<S> extends true ? MergeRecords<T, S> : MergeAssignable<T, S>) : MergeAssignable<T, S>;
68
+ type MergeAssignable<T, S> = [S] extends [Primitive | NonMergeable] ? S : [S] extends [T] ? T : [T] extends [S] ? S : MergeFallback<T, S>;
69
+ type MergeFallback<T, S> = S extends Primitive ? S : S extends readonly unknown[] ? (T extends readonly unknown[] ? MergeArrays<T, S> : T extends Primitive | NonMergeable ? S : T extends object ? T & S : S) : S extends NonMergeable ? S : S extends object ? (T extends readonly unknown[] ? T & S : T extends Primitive | NonMergeable ? S : T extends object ? MergeRecords<T, S> : S) : S;
34
70
  type MergeArrays<T extends readonly unknown[], S extends readonly unknown[]> = T extends readonly [] ? S : S extends readonly [] ? T : T extends readonly [infer TH, ...infer TR] ? S extends readonly [infer SH, ...infer SR] ? [Merge<TH, SH>, ...MergeArrays<TR, SR>] : Array<T[number] | S[number]> : Array<T[number] | S[number]>;
35
- type MergeRecords<T extends object, S extends object> = Simplify<Omit<T, keyof S> & Omit<S, keyof T> & { [K in keyof T & keyof S]: Merge<T[K], S[K]> }>;
71
+ type MergeRecords<T, S> = Simplify<Omit<T, keyof S> & Omit<S, keyof T> & { [K in keyof T & keyof S]: Merge<T[K], S[K]> }>;
36
72
  //#endregion
37
73
  export { Merge };
@@ -1,4 +1,8 @@
1
1
  import { ObjectKeys } from "./ObjectKeys.mjs";
2
+ import { IsAny } from "./IsAny.mjs";
3
+ import { IsEqual } from "./IsEqual.mjs";
4
+ import { IsUnknown } from "./IsUnknown.mjs";
5
+ import { Primitive } from "./Primitive.mjs";
2
6
  import { Simplify } from "./Simplify.mjs";
3
7
  import { Merge } from "./Merge.mjs";
4
8
  import { ToCamelCaseKeys } from "./ToCamelCaseKeys.mjs";
@@ -6,12 +10,10 @@ import { ToConstantCaseKeys } from "./ToConstantCaseKeys.mjs";
6
10
  import { ToKebabCaseKeys } from "./ToKebabCaseKeys.mjs";
7
11
  import { ToPascalCaseKeys } from "./ToPascalCaseKeys.mjs";
8
12
  import { ToSnakeCaseKeys } from "./ToSnakeCaseKeys.mjs";
9
- import { Primitive } from "./Primitive.mjs";
10
13
  import { DeepPartial } from "./DeepPartial.mjs";
11
14
  import { DeepReadonly } from "./DeepReadonly.mjs";
12
15
  import { DistributiveOmit } from "./DistributiveOmit.mjs";
13
16
  import { EmptyObject } from "./EmptyObject.mjs";
14
- import { IsEqual } from "./IsEqual.mjs";
15
17
  import { JSONValue } from "./JSONValue.mjs";
16
18
  import { NonEmptyArray } from "./NonEmptyArray.mjs";
17
19
  import { SetOptional } from "./SetOptional.mjs";
@@ -19,4 +21,4 @@ import { SetRequired } from "./SetRequired.mjs";
19
21
  import { UnknownRecord } from "./UnknownRecord.mjs";
20
22
  import { ValueOf } from "./ValueOf.mjs";
21
23
  import { Writable } from "./Writable.mjs";
22
- export { type DeepPartial, type DeepReadonly, type DistributiveOmit, type EmptyObject, type IsEqual, type JSONValue, type Merge, type NonEmptyArray, type ObjectKeys, type Primitive, type SetOptional, type SetRequired, type Simplify, type ToCamelCaseKeys, type ToConstantCaseKeys, type ToKebabCaseKeys, type ToPascalCaseKeys, type ToSnakeCaseKeys, type UnknownRecord, type ValueOf, type Writable };
24
+ export { type DeepPartial, type DeepReadonly, type DistributiveOmit, type EmptyObject, type IsAny, type IsEqual, type IsUnknown, type JSONValue, type Merge, type NonEmptyArray, type ObjectKeys, type Primitive, type SetOptional, type SetRequired, type Simplify, type ToCamelCaseKeys, type ToConstantCaseKeys, type ToKebabCaseKeys, type ToPascalCaseKeys, type ToSnakeCaseKeys, type UnknownRecord, type ValueOf, type Writable };
@@ -1,4 +1,8 @@
1
1
  import { ObjectKeys } from "./ObjectKeys.js";
2
+ import { IsAny } from "./IsAny.js";
3
+ import { IsEqual } from "./IsEqual.js";
4
+ import { IsUnknown } from "./IsUnknown.js";
5
+ import { Primitive } from "./Primitive.js";
2
6
  import { Simplify } from "./Simplify.js";
3
7
  import { Merge } from "./Merge.js";
4
8
  import { ToCamelCaseKeys } from "./ToCamelCaseKeys.js";
@@ -6,12 +10,10 @@ import { ToConstantCaseKeys } from "./ToConstantCaseKeys.js";
6
10
  import { ToKebabCaseKeys } from "./ToKebabCaseKeys.js";
7
11
  import { ToPascalCaseKeys } from "./ToPascalCaseKeys.js";
8
12
  import { ToSnakeCaseKeys } from "./ToSnakeCaseKeys.js";
9
- import { Primitive } from "./Primitive.js";
10
13
  import { DeepPartial } from "./DeepPartial.js";
11
14
  import { DeepReadonly } from "./DeepReadonly.js";
12
15
  import { DistributiveOmit } from "./DistributiveOmit.js";
13
16
  import { EmptyObject } from "./EmptyObject.js";
14
- import { IsEqual } from "./IsEqual.js";
15
17
  import { JSONValue } from "./JSONValue.js";
16
18
  import { NonEmptyArray } from "./NonEmptyArray.js";
17
19
  import { SetOptional } from "./SetOptional.js";
@@ -19,4 +21,4 @@ import { SetRequired } from "./SetRequired.js";
19
21
  import { UnknownRecord } from "./UnknownRecord.js";
20
22
  import { ValueOf } from "./ValueOf.js";
21
23
  import { Writable } from "./Writable.js";
22
- export { type DeepPartial, type DeepReadonly, type DistributiveOmit, type EmptyObject, type IsEqual, type JSONValue, type Merge, type NonEmptyArray, type ObjectKeys, type Primitive, type SetOptional, type SetRequired, type Simplify, type ToCamelCaseKeys, type ToConstantCaseKeys, type ToKebabCaseKeys, type ToPascalCaseKeys, type ToSnakeCaseKeys, type UnknownRecord, type ValueOf, type Writable };
24
+ export { type DeepPartial, type DeepReadonly, type DistributiveOmit, type EmptyObject, type IsAny, type IsEqual, type IsUnknown, type JSONValue, type Merge, type NonEmptyArray, type ObjectKeys, type Primitive, type SetOptional, type SetRequired, type Simplify, type ToCamelCaseKeys, type ToConstantCaseKeys, type ToKebabCaseKeys, type ToPascalCaseKeys, type ToSnakeCaseKeys, type UnknownRecord, type ValueOf, type Writable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-toolkit",
3
- "version": "1.52.0-dev.2135+aaeb0753",
3
+ "version": "1.52.0-dev.2137+e472583b",
4
4
  "description": "A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.",
5
5
  "homepage": "https://es-toolkit.dev",
6
6
  "bugs": "https://github.com/toss/es-toolkit/issues",