nhb-toolbox 4.20.32 → 4.20.40

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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ All notable changes to the package will be documented here.
6
6
 
7
7
  ---
8
8
 
9
+ ## [4.20.40] - 2025-09-18
10
+
11
+ - **Added** new **utility types**: `DeepPartialAll`, `Join`,`Split` along with `ValidArray`, `List` and _more_.
12
+
9
13
  ## [4.20.32] - 2025-09-17
10
14
 
11
15
  - **Renamed** `isPastParticiple()` method to `isParticiple()` in `Verbalizer/verbalizer`.
@@ -38,17 +38,17 @@ export type NonNullishPrimitiveKey<T> = {
38
38
  /** Falsy primitive type */
39
39
  export type FalsyPrimitive = false | 0 | '' | null | undefined;
40
40
  /** A generic class constructor */
41
- export type Constructor = new (...args: any[]) => unknown;
41
+ export type Constructor = new (...args: any) => any;
42
42
  /** Generic function type */
43
- export type GenericFn = (...args: unknown[]) => unknown;
43
+ export type GenericFn = (...args: any) => any;
44
44
  /** Generic function type that returns `void` */
45
- export type VoidFunction = (...args: any[]) => void;
45
+ export type VoidFunction = (...args: any) => void;
46
46
  /** Debounced function type after certain delay */
47
47
  export type DelayedFn<T extends VoidFunction> = (...args: Parameters<T>) => void;
48
48
  /** Throttled function type after specific delay */
49
49
  export type ThrottledFn<T extends VoidFunction> = (...args: Parameters<T>) => void;
50
50
  /** Asynchronous function type */
51
- export type AsyncFunction<T> = (...args: unknown[]) => Promise<T>;
51
+ export type AsyncFunction<T> = (...args: any) => Promise<T>;
52
52
  /** Advanced types to exclude from counting as object key */
53
53
  export type AdvancedTypes = Array<unknown> | File | FileList | Chronos | DateLike | Blob | Date | RegExp | WeakMap<WeakKey, unknown> | WeakSet<WeakKey> | Map<unknown, unknown> | Set<unknown> | Function | GenericFn | VoidFunction | AsyncFunction<unknown> | Promise<unknown> | Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError | URIError | bigint | symbol;
54
54
  /** Helper to detect if a type has methods */
@@ -76,4 +76,61 @@ export interface ClassDetails {
76
76
  }
77
77
  /** Literal type for `partial` and `required` */
78
78
  export type PartialOrRequired = 'partial' | 'required';
79
+ /**
80
+ * - Utility type to assert that a given type condition evaluates to `true`.
81
+ *
82
+ * @remarks
83
+ * - This type is mainly used in **type-level tests** to enforce that a condition (usually produced by {@link Equal}) is satisfied.
84
+ * - If the condition is not `true`, TypeScript will raise an error at compile time.
85
+ *
86
+ * @example
87
+ * // Passes ✅
88
+ * type Test1 = Expect<true>;
89
+ *
90
+ * // Fails ❌ - will cause a type error
91
+ * type Test2 = Expect<false>;
92
+ */
93
+ export type Expect<T extends true> = T;
94
+ /**
95
+ * * Utility type that checks whether two types `X` and `Y` are strictly equal.
96
+ *
97
+ * @remarks
98
+ * - This type uses conditional types and generic inference tricks to compare whether two types are identical.
99
+ * - It resolves to `true` if `X` and `Y` are the same type, otherwise `false`.
100
+ *
101
+ * _Typically used together with {@link Expect} for type-level assertions in tests._
102
+ *
103
+ * @example
104
+ * type Test1 = Equal<string, string>; // true
105
+ * type Test2 = Equal<string, number>; // false
106
+ *
107
+ * // Example with Expect
108
+ * type Check = Expect<Equal<'a', 'a'>>; // ✅ Compiles
109
+ * type Fail = Expect<Equal<'a', 'b'>>; // ❌ Type error
110
+ */
111
+ export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
112
+ /**
113
+ * * Ensures that an array has **at least one element**.
114
+ *
115
+ * @remarks
116
+ * - This type enforces non-empty arrays by requiring the first element `T`, followed by zero or more additional `T`s.
117
+ *
118
+ * @example
119
+ * type NonEmpty = ValidArray<number>; // [number, ...number[]]
120
+ * const arr1: NonEmpty = [1]; // ✅ OK
121
+ * const arr2: NonEmpty = []; // ❌ Error (empty array not allowed)
122
+ */
123
+ export type ValidArray<T> = [T, ...Array<T>];
124
+ /**
125
+ * * A readonly array of elements of type `T`.
126
+ *
127
+ * @remarks
128
+ * - Shorthand for `ReadonlyArray<T>`. Used to represent immutable lists.
129
+ *
130
+ * @example
131
+ * type Numbers = List<number>; // readonly number[]
132
+ * const arr: Numbers = [1, 2, 3]; // ✅ OK
133
+ * arr.push(4); // ❌ Error (readonly)
134
+ */
135
+ export type List<T = any> = ReadonlyArray<T>;
79
136
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { GenericObject, NestedPrimitiveKey } from '../object/types';
2
- import type { AdvancedTypes, Numeric } from '../types/index';
2
+ import type { AdvancedTypes, List, NormalPrimitive, Numeric } from '../types/index';
3
3
  /** Options to initialize Paginator */
4
4
  export interface PaginatorOptions {
5
5
  /** The total number of items. */
@@ -72,7 +72,11 @@ export type ValueOf<T> = T[keyof T];
72
72
  */
73
73
  export type KeysOfUnion<T> = T extends T ? keyof T : never;
74
74
  /**
75
- * * Recursively makes all properties in an object type optional.
75
+ * * Recursively makes all potential standard js object properties optional.
76
+ *
77
+ * @remarks
78
+ * - It excludes complex types like `Array`, `Map`, `File`, `Date`, `Chronos` etc. from being recursively partial.
79
+ * - Please, refer to {@link AdvancedTypes} to learn more about these complex types.
76
80
  *
77
81
  * @example
78
82
  * type Config = { a: string; nested: { b: number } };
@@ -82,6 +86,17 @@ export type KeysOfUnion<T> = T extends T ? keyof T : never;
82
86
  export type DeepPartial<T> = {
83
87
  [K in keyof T]?: T[K] extends AdvancedTypes ? T[K] : T[K] extends object ? DeepPartial<T[K]> : T[K];
84
88
  };
89
+ /**
90
+ * * Recursively makes all properties in any object or array type optional.
91
+ *
92
+ * @example
93
+ * type Config = { a: string; nested: { b: number } };
94
+ * type PartialConfig = DeepPartial<Config>;
95
+ * // { a?: string; nested?: { b?: number } }
96
+ */
97
+ export type DeepPartialAll<T> = T extends Array<infer El> ? Array<DeepPartialAll<El>> : {
98
+ [K in keyof T]?: DeepPartialAll<T[K]>;
99
+ };
85
100
  /**
86
101
  * * Removes `readonly` modifiers from all properties of an object type.
87
102
  *
@@ -444,4 +459,67 @@ export type RequireExactly<T extends GenericObject, N extends number> = {
444
459
  * const s4: OneOrTwo = {}; // ❌ (0 keys)
445
460
  */
446
461
  export type RequireBetween<T extends GenericObject, Min extends number, Max extends number, C extends unknown[] = BuildTuple<Max>, Acc extends unknown[] = BuildTuple<Min>> = RequireExactly<T, Acc['length']> | (Acc['length'] extends Max ? never : RequireBetween<T, Min, Max, C, [...Acc, unknown]>);
462
+ /**
463
+ * * Cast one type to another while preserving compatibility.
464
+ *
465
+ * @remarks
466
+ * - Ensures that `A1` extends `A2`. If not, falls back to `A2`.
467
+ * - Useful for enforcing constraints on generics or parameters.
468
+ *
469
+ * @param A1 - Type to check.
470
+ * @param A2 - Type to cast to.
471
+ * @returns `A1` if it extends `A2`, otherwise `A2`.
472
+ *
473
+ * @example
474
+ * type T0 = Cast<'42', string>; // '42'
475
+ * type T1 = Cast<'42', number>; // number
476
+ * type T2 = Cast<42, number>; // 42
477
+ */
478
+ export type Cast<A1, A2> = A1 extends A2 ? A1 : A2;
479
+ /**
480
+ * * Remove the last element of a list (array).
481
+ *
482
+ * @remarks Produces a new tuple/list type with the last element removed.
483
+ *
484
+ * @example
485
+ * type T0 = Pop<[1, 2, 3]>; // [1, 2]
486
+ * type T1 = Pop<[]>; // []
487
+ * type T2 = Pop<['a']>; // []
488
+ */
489
+ export type Pop<L extends List> = L extends readonly [...infer El, any] | readonly [...infer El, any?] ? El : L;
490
+ type __Split<S extends string, D extends string, T extends string[] = []> = S extends `${infer BS}${D}${infer AS}` ? __Split<AS, D, [...T, BS]> : [...T, S];
491
+ type _Split<S extends string, D extends string = ''> = D extends '' ? Pop<__Split<S, D>> : __Split<S, D>;
492
+ /**
493
+ * ✂️ Split a string literal by a given delimiter into a list of strings.
494
+ *
495
+ * @remarks
496
+ * Produces a tuple of substrings by splitting `S` at each occurrence of `D`.
497
+ *
498
+ * @param S - String literal to split.
499
+ * @param D - Delimiter to split on (default: empty string, i.e., character split).
500
+ * @returns A list of string literals.
501
+ *
502
+ * @example
503
+ * type T0 = Split<'a,b,c', ','>; // ['a', 'b', 'c']
504
+ * type T1 = Split<'hello', ''>; // ['h', 'e', 'l', 'l', 'o']
505
+ * type T2 = Split<'foo-bar', '-'>; // ['foo', 'bar']
506
+ */
507
+ export type Split<S extends string, D extends string = ''> = _Split<S, D> extends infer X ? Cast<X, string[]> : never;
508
+ type _Join<T extends List, D extends string> = T extends [] ? '' : T extends [NormalPrimitive] ? `${T[0]}` : T extends [NormalPrimitive, ...infer R] ? `${T[0]}${D}${_Join<R, D>}` : string;
509
+ /**
510
+ * * Join a list of string/number/boolean literals into a single string.
511
+ *
512
+ * @remarks
513
+ * Concatenates elements of `T` into a single string, separated by delimiter `D`.
514
+ *
515
+ * @param T - List of string/number/boolean literals.
516
+ * @param D - Delimiter to insert between elements (default: space `" "`).
517
+ * @returns A concatenated string literal.
518
+ *
519
+ * @example
520
+ * type T0 = Join<['a', 'b', 'c'], ','>; // "a,b,c"
521
+ * type T1 = Join<['2025', '09', '18'], '-'>; // "2025-09-18"
522
+ * type T2 = Join<['hello', 'world']>; // "hello world"
523
+ */
524
+ export type Join<T extends List<NormalPrimitive>, D extends string = ' '> = _Join<T, D> extends infer X ? Cast<X, string> : never;
447
525
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhb-toolbox",
3
- "version": "4.20.32",
3
+ "version": "4.20.40",
4
4
  "description": "A versatile collection of smart, efficient, and reusable utility functions and classes for everyday development needs.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",