uni-types 1.0.0 → 1.1.0

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/dist/index.d.mts CHANGED
@@ -1,3 +1,97 @@
1
+ //#region src/brand/index.d.ts
2
+ /**
3
+ * Brand/Opaque types for nominal typing
4
+ */
5
+ /**
6
+ * Brand a type for nominal typing
7
+ * Creates a unique type that cannot be accidentally mixed with other branded types
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * type UserId = Brand<string, 'UserId'>
12
+ * type OrderId = Brand<string, 'OrderId'>
13
+ *
14
+ * const userId: UserId = 'user-123' as UserId
15
+ * const orderId: OrderId = 'order-456' as OrderId
16
+ *
17
+ * // These won't mix - type safety!
18
+ * // const wrong: OrderId = userId // Error!
19
+ * ```
20
+ */
21
+ type Brand<T, B extends string> = T & {
22
+ __brand: B;
23
+ };
24
+ /**
25
+ * Unbrand a branded type - extracts the underlying type
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * type UserId = Brand<string, 'UserId'>
30
+ * Unbrand<UserId> // string
31
+ * ```
32
+ */
33
+ type Unbrand<T> = T extends Brand<infer U, infer _> ? U : T;
34
+ /**
35
+ * Common branded types for convenience
36
+ */
37
+ type BrandedString<B extends string> = Brand<string, B>;
38
+ type BrandedNumber<B extends string> = Brand<number, B>;
39
+ //#endregion
40
+ //#region src/conditional/index.d.ts
41
+ /**
42
+ * Conditional type utilities for cleaner type logic
43
+ */
44
+ /**
45
+ * If-then-else at type level
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * If<true, string, number> // string
50
+ * If<false, string, number> // number
51
+ * ```
52
+ */
53
+ type If<C extends boolean, T, F> = C extends true ? T : F;
54
+ /**
55
+ * Not operator for boolean types
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * Not<true> // false
60
+ * Not<false> // true
61
+ * ```
62
+ */
63
+ type Not<B extends boolean> = B extends true ? false : true;
64
+ /**
65
+ * And operator for boolean types
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * And<true, true> // true
70
+ * And<true, false> // false
71
+ * ```
72
+ */
73
+ type And<A extends boolean, B extends boolean> = A extends true ? B : false;
74
+ /**
75
+ * Or operator for boolean types
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * Or<true, false> // true
80
+ * Or<false, false> // false
81
+ * ```
82
+ */
83
+ type Or<A extends boolean, B extends boolean> = A extends true ? true : B;
84
+ /**
85
+ * Type constraint assertion - ensures T extends U
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * Assert<string | number, string> // string
90
+ * Assert<string, number> // never
91
+ * ```
92
+ */
93
+ type Assert<T, U extends T> = T extends U ? T : never;
94
+ //#endregion
1
95
  //#region src/core/omit.d.ts
2
96
  /**
3
97
  * Make all properties required except specified ones
@@ -111,7 +205,7 @@ type Last<T extends readonly unknown[]> = T extends readonly [...unknown[], infe
111
205
  * Tail<[1]> // []
112
206
  * ```
113
207
  */
114
- type Tail<T extends readonly unknown[]> = T extends readonly [unknown, ...infer R] ? R : [];
208
+ type Tail$1<T extends readonly unknown[]> = T extends readonly [unknown, ...infer R] ? R : [];
115
209
  /**
116
210
  * Get all elements except the last (init)
117
211
  *
@@ -160,6 +254,109 @@ type TupleLength<T extends readonly unknown[]> = T['length'];
160
254
  */
161
255
  type IsEmptyTuple<T extends readonly unknown[]> = T extends readonly [] ? true : false;
162
256
  //#endregion
257
+ //#region src/utils/path.d.ts
258
+ type Primitive$1 = string | number | boolean | null | undefined | symbol | bigint;
259
+ type Join<K, P> = K extends string | number ? P extends string | number ? `${K}${'' extends P ? '' : '.'}${P}` : never : never;
260
+ type Prev$1 = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
261
+ /**
262
+ * Get all possible paths to nested properties
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * interface Obj {
267
+ * a: {
268
+ * b: string
269
+ * c: {
270
+ * d: number
271
+ * }
272
+ * }
273
+ * }
274
+ *
275
+ * type P = Paths<Obj>
276
+ * // 'a' | 'a.b' | 'a.c' | 'a.c.d'
277
+ * ```
278
+ */
279
+ type Paths<T, D extends number = 10> = [D] extends [never] ? never : T extends Primitive$1 ? never : { [K in keyof T]: T[K] extends Primitive$1 ? `${K & string}` : Join<K, Paths<T[K], Prev$1[D]>> }[keyof T];
280
+ /**
281
+ * Get the value type at a given path
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * interface Obj {
286
+ * a: {
287
+ * b: string
288
+ * }
289
+ * }
290
+ *
291
+ * type V = PathValue<Obj, 'a.b'> // string
292
+ * ```
293
+ */
294
+ type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue<T[K], Rest> : never : P extends keyof T ? T[P] : never;
295
+ /**
296
+ * Split a path string into an array
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * SplitPath<'a.b.c'> // ['a', 'b', 'c']
301
+ * ```
302
+ */
303
+ type SplitPath<S extends string, Acc extends string[] = []> = S extends `${infer H}.${infer T}` ? SplitPath<T, [...Acc, H]> : S extends `${infer H}` ? [...Acc, H] : Acc;
304
+ //#endregion
305
+ //#region src/deep/path.d.ts
306
+ type PathSegments<_T, P extends string> = P extends '' ? [] : SplitPath<P>;
307
+ /**
308
+ * Deep omit by path - removes properties at specified paths
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * interface User {
313
+ * profile: {
314
+ * name: string
315
+ * email: string
316
+ * settings: {
317
+ * theme: string
318
+ * lang: string
319
+ * }
320
+ * }
321
+ * }
322
+ *
323
+ * DeepOmit<User, 'profile.settings'>
324
+ * // { profile: { name: string; email: string } }
325
+ * ```
326
+ */
327
+ type DeepOmit<T, P extends string> = T extends object ? P extends '' ? T : DeepOmitBySegments<T, PathSegments<T, P>> : T;
328
+ type DeepOmitBySegments<T, Segments extends string[]> = Segments extends [infer First extends string, ...infer Rest extends string[]] ? First extends keyof T ? Rest extends [] ? Omit<T, First> : { [K in keyof T]: K extends First ? DeepOmitBySegments<T[K], Rest> : T[K] } : T : T;
329
+ /**
330
+ * Deep pick by path - keeps only properties at specified paths
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * interface User {
335
+ * profile: {
336
+ * name: string
337
+ * email: string
338
+ * settings: {
339
+ * theme: string
340
+ * lang: string
341
+ * }
342
+ * }
343
+ * }
344
+ *
345
+ * DeepPick<User, 'profile.name' | 'profile.settings.theme'>
346
+ * // { profile: { name: string; settings: { theme: string } } }
347
+ * ```
348
+ */
349
+ type DeepPick<T, P extends string> = T extends object ? P extends '' ? T : DeepPickBySegments<T, PathSegments<T, P>> : T;
350
+ type DeepPickBySegments<T, Segments extends string[]> = Segments extends [infer First extends string, ...infer Rest extends string[]] ? First extends keyof T ? Rest extends [] ? Pick<T, First> : { [K in First]: DeepPickBySegments<T[K], Rest> } : Record<string, never> : T;
351
+ /**
352
+ * Deep pick for union paths
353
+ */
354
+ type DeepPickPaths<T, P extends string> = P extends P ? DeepPick<T, P> : never;
355
+ /**
356
+ * Deep omit for union paths
357
+ */
358
+ type DeepOmitPaths<T, P extends string> = P extends P ? DeepOmit<T, P> : never;
359
+ //#endregion
163
360
  //#region src/deep/index.d.ts
164
361
  type BuiltIn = Date | ((...args: unknown[]) => unknown) | Map<unknown, unknown> | Set<unknown> | RegExp;
165
362
  /**
@@ -231,6 +428,123 @@ type DeepReadonly<T> = T extends BuiltIn ? T : T extends Map<infer K, infer V> ?
231
428
  */
232
429
  type DeepMutable<T> = T extends BuiltIn ? T : T extends Map<infer K, infer V> ? Map<DeepMutable<K>, DeepMutable<V>> : T extends Set<infer V> ? Set<DeepMutable<V>> : T extends readonly (infer E)[] ? DeepMutable<E>[] : T extends object ? { -readonly [P in keyof T]: DeepMutable<T[P]> } : T;
233
430
  //#endregion
431
+ //#region src/functions/index.d.ts
432
+ /**
433
+ * Function type utilities
434
+ */
435
+ /**
436
+ * Get function parameters as tuple
437
+ *
438
+ * @example
439
+ * ```ts
440
+ * type Fn = (a: string, b: number) => boolean
441
+ * Parameters<Fn> // [string, number]
442
+ * ```
443
+ */
444
+ type Parameters<T> = T extends ((...args: infer P) => any) ? P : never;
445
+ /**
446
+ * Get function return type
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * type Fn = (a: string) => number
451
+ * ReturnType<Fn> // number
452
+ * ```
453
+ */
454
+ type ReturnType<T> = T extends ((...args: any[]) => infer R) ? R : any;
455
+ /**
456
+ * Get Nth parameter type (0-indexed)
457
+ *
458
+ * @example
459
+ * ```ts
460
+ * type Fn = (a: string, b: number, c: boolean) => void
461
+ * NthParameter<Fn, 0> // string
462
+ * NthParameter<Fn, 1> // number
463
+ * NthParameter<Fn, 2> // boolean
464
+ * ```
465
+ */
466
+ type NthParameter<T, N extends number> = T extends ((...args: infer P) => any) ? P[N] : never;
467
+ /**
468
+ * Extract async function return type (unwraps Promise)
469
+ *
470
+ * @example
471
+ * ```ts
472
+ * type AsyncFn = () => Promise<string>
473
+ * AsyncReturnType<AsyncFn> // string
474
+ * ```
475
+ */
476
+ type AsyncReturnType<T> = T extends ((...args: any[]) => Promise<infer R>) ? R : T extends ((...args: any[]) => infer R) ? R : never;
477
+ /**
478
+ * Get function this parameter type
479
+ *
480
+ * @example
481
+ * ```ts
482
+ * type Fn = (this: { x: number }) => void
483
+ * ThisParameterType<Fn> // { x: number }
484
+ * ```
485
+ */
486
+ type ThisParameterType<T> = T extends ((this: infer U, ...args: any[]) => any) ? U : unknown;
487
+ /**
488
+ * Omit this parameter from function type
489
+ *
490
+ * @example
491
+ * ```ts
492
+ * type Fn = (this: { x: number }, a: string) => void
493
+ * OmitThisParameter<Fn> // (a: string) => void
494
+ * ```
495
+ */
496
+ type OmitThisParameter<T> = T extends ((this: any, ...args: infer A) => infer R) ? (...args: A) => R : T;
497
+ /**
498
+ * Check if type is a function
499
+ *
500
+ * @example
501
+ * ```ts
502
+ * IsFunction<() => void> // true
503
+ * IsFunction<string> // false
504
+ * ```
505
+ */
506
+ type IsFunction<T> = T extends ((...args: any[]) => any) ? true : false;
507
+ /**
508
+ * Check if type is an async function
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * IsAsyncFunction<() => Promise<string>> // true
513
+ * IsAsyncFunction<() => string> // false
514
+ * ```
515
+ */
516
+ type IsAsyncFunction<T> = T extends ((...args: any[]) => Promise<any>) ? true : false;
517
+ /**
518
+ * Make function parameters optional
519
+ *
520
+ * @example
521
+ * ```ts
522
+ * type Fn = (a: string, b: number) => void
523
+ * OptionalParameters<Fn> // (a?: string, b?: number) => void
524
+ * ```
525
+ */
526
+ type OptionalParameters<T> = T extends ((...args: any[]) => infer R) ? (...args: Partial<Parameters<T>>) => R : never;
527
+ /**
528
+ * Append a parameter to a function
529
+ *
530
+ * @example
531
+ * ```ts
532
+ * type Fn = (a: string) => void
533
+ * AppendParameter<Fn, number> // (a: string, b: number) => void
534
+ * ```
535
+ */
536
+ type AppendParameter<T, P> = T extends ((...args: infer A) => infer R) ? (...args: [...A, P]) => R : never;
537
+ /**
538
+ * Prepend a parameter to a function
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * type Fn = (a: string) => void
543
+ * PrependParameter<Fn, number> // (a: number, b: string) => void
544
+ * ```
545
+ */
546
+ type PrependParameter<T, P> = T extends ((...args: infer A) => infer R) ? (...args: [P, ...A]) => R : never;
547
+ //#endregion
234
548
  //#region src/guards/index.d.ts
235
549
  /**
236
550
  * Check if type is an array
@@ -345,54 +659,6 @@ type FunctionOnly<T> = Pick<T, FunctionKeys<T>>;
345
659
  */
346
660
  type DataOnly<T> = Pick<T, NonFunctionKeys<T>>;
347
661
  //#endregion
348
- //#region src/utils/path.d.ts
349
- type Primitive = string | number | boolean | null | undefined | symbol | bigint;
350
- type Join<K, P> = K extends string | number ? P extends string | number ? `${K}${'' extends P ? '' : '.'}${P}` : never : never;
351
- type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
352
- /**
353
- * Get all possible paths to nested properties
354
- *
355
- * @example
356
- * ```ts
357
- * interface Obj {
358
- * a: {
359
- * b: string
360
- * c: {
361
- * d: number
362
- * }
363
- * }
364
- * }
365
- *
366
- * type P = Paths<Obj>
367
- * // 'a' | 'a.b' | 'a.c' | 'a.c.d'
368
- * ```
369
- */
370
- type Paths<T, D extends number = 10> = [D] extends [never] ? never : T extends Primitive ? never : { [K in keyof T]: T[K] extends Primitive ? `${K & string}` : Join<K, Paths<T[K], Prev[D]>> }[keyof T];
371
- /**
372
- * Get the value type at a given path
373
- *
374
- * @example
375
- * ```ts
376
- * interface Obj {
377
- * a: {
378
- * b: string
379
- * }
380
- * }
381
- *
382
- * type V = PathValue<Obj, 'a.b'> // string
383
- * ```
384
- */
385
- type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue<T[K], Rest> : never : P extends keyof T ? T[P] : never;
386
- /**
387
- * Split a path string into an array
388
- *
389
- * @example
390
- * ```ts
391
- * SplitPath<'a.b.c'> // ['a', 'b', 'c']
392
- * ```
393
- */
394
- type SplitPath<S extends string, Acc extends string[] = []> = S extends `${infer H}.${infer T}` ? SplitPath<T, [...Acc, H]> : S extends `${infer H}` ? [...Acc, H] : Acc;
395
- //#endregion
396
662
  //#region src/utils/index.d.ts
397
663
  /**
398
664
  * Merge two types (latter overrides former)
@@ -412,7 +678,7 @@ type Merge<T, U> = Omit<T, keyof U> & U;
412
678
  * NonNullable<string | null | undefined> // string
413
679
  * ```
414
680
  */
415
- type NonNullable<T> = T & {};
681
+ type NonNullable$1<T> = T & {};
416
682
  /**
417
683
  * Exclusive properties (only one can be selected)
418
684
  *
@@ -426,7 +692,7 @@ type Exclusive<T, K extends keyof T> = T extends unknown ? Omit<T, K> & { [P in
426
692
  /**
427
693
  * Remove null and undefined from all properties
428
694
  */
429
- type NoNullish<T> = { [K in keyof T]: NonNullable<T[K]> };
695
+ type NoNullish<T> = { [K in keyof T]: NonNullable$1<T[K]> };
430
696
  /**
431
697
  * Make all properties optional while preserving undefined/null values
432
698
  */
@@ -544,4 +810,511 @@ type WritableKeys<T> = { [K in keyof T]: IfEquals<Readonly<Pick<T, K>>, Pick<T,
544
810
  type ReadonlyKeys<T> = { [K in keyof T]: IfEquals<Readonly<Pick<T, K>>, Pick<T, K>, never, K> }[keyof T];
545
811
  type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? A : B;
546
812
  //#endregion
547
- export { ArrayElement, AtLeastOne, Awaited, CamelCase, CamelCaseKeys, DataOnly, DeepMutable, DeepPartial, DeepReadonly, DeepRequired, Exclusive, FirstParameter, Flatten, FunctionKeys, FunctionOnly, Head, Init, IsAny, IsArray, IsEmptyTuple, IsEqual, IsNever, IsTuple, IsUnknown, Last, Literal, LiteralBoolean, LiteralNumber, LiteralString, LoosePartial, Maybe, Merge, NoNullish, NonFunctionKeys, NonNullable, Nullable, OmitPartial, OmitRequired, Optional, OptionalKeys, PathValue, Paths, PickPartial, PickRequired, ReadonlyKeys, RequiredKeys, Reverse, SnakeCase, SnakeCaseKeys, SplitPath, StrictExclude, StrictExtract, Tail, TupleLength, UnionToIntersection, UnionToTuple, ValueOf, WritableKeys };
813
+ //#region src/keys/index.d.ts
814
+ /**
815
+ * Get all keys as literal union
816
+ *
817
+ * @example
818
+ * ```ts
819
+ * Keys<{ a: string; b: number }> // 'a' | 'b'
820
+ * ```
821
+ */
822
+ type Keys<T> = keyof T;
823
+ /**
824
+ * Rename object keys based on a mapping
825
+ *
826
+ * @example
827
+ * ```ts
828
+ * RenameKeys<{ oldName: string }, { oldName: 'newName' }>
829
+ * // { newName: string }
830
+ * ```
831
+ */
832
+ type RenameKeys<T, M extends Record<string, string>> = { [K in keyof T as K extends keyof M ? M[K] : K]: T[K] };
833
+ /**
834
+ * Prefix all keys with a string
835
+ *
836
+ * @example
837
+ * ```ts
838
+ * PrefixKeys<{ a: string; b: number }, 'data'>
839
+ * // { dataA: string; dataB: number }
840
+ * ```
841
+ */
842
+ type PrefixKeys<T, P extends string> = { [K in keyof T as `${P}${Capitalize<K & string>}`]: T[K] };
843
+ /**
844
+ * Suffix all keys with a string
845
+ *
846
+ * @example
847
+ * ```ts
848
+ * SuffixKeys<{ a: string; b: number }, 'Data'>
849
+ * // { aData: string; bData: number }
850
+ * ```
851
+ */
852
+ type SuffixKeys<T, S extends string> = { [K in keyof T as `${K & string}${S}`]: T[K] };
853
+ /**
854
+ * Convert keys to PascalCase
855
+ *
856
+ * @example
857
+ * ```ts
858
+ * PascalCaseKeys<{ helloWorld: string }>
859
+ * // { HelloWorld: string }
860
+ * ```
861
+ */
862
+ type PascalCaseKeys<T> = { [K in keyof T as Capitalize<CamelCase<K & string>>]: T[K] };
863
+ /**
864
+ * Get keys by value type
865
+ *
866
+ * @example
867
+ * ```ts
868
+ * interface User {
869
+ * name: string
870
+ * age: number
871
+ * email: string
872
+ * }
873
+ *
874
+ * KeysByValueType<User, string> // 'name' | 'email'
875
+ * ```
876
+ */
877
+ type KeysByValueType<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
878
+ /**
879
+ * Get keys that match a pattern
880
+ *
881
+ * @example
882
+ * ```ts
883
+ * interface User {
884
+ * userName: string
885
+ * userId: number
886
+ * userEmail: string
887
+ * age: number
888
+ * }
889
+ *
890
+ * FilterKeys<User, `user${string}`> // 'userName' | 'userId' | 'userEmail'
891
+ * ```
892
+ */
893
+ type FilterKeys<T, P extends string> = keyof T extends infer K ? K extends P ? K : never : never;
894
+ //#endregion
895
+ //#region src/numeric/index.d.ts
896
+ /**
897
+ * Numeric type operations for compile-time arithmetic
898
+ */
899
+ type NumberToArray<N extends number, Acc extends 0[] = []> = Acc['length'] extends N ? Acc : NumberToArray<N, [...Acc, 0]>;
900
+ /**
901
+ * Increment number type
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * Inc<5> // 6
906
+ * Inc<0> // 1
907
+ * ```
908
+ */
909
+ type Inc<N extends number> = [...NumberToArray<N>, 0]['length'];
910
+ /**
911
+ * Decrement number type
912
+ *
913
+ * @example
914
+ * ```ts
915
+ * Dec<5> // 4
916
+ * Dec<1> // 0
917
+ * Dec<0> // 0 (clamped)
918
+ * ```
919
+ */
920
+ type Dec<N extends number> = N extends 0 ? 0 : NumberToArray<N> extends [0, ...infer Rest] ? Rest['length'] : 0;
921
+ /**
922
+ * Add two number types
923
+ *
924
+ * @example
925
+ * ```ts
926
+ * Add<3, 4> // 7
927
+ * Add<0, 5> // 5
928
+ * ```
929
+ */
930
+ type Add<A extends number, B extends number> = [...NumberToArray<A>, ...NumberToArray<B>]['length'];
931
+ /**
932
+ * Subtract two number types
933
+ *
934
+ * @example
935
+ * ```ts
936
+ * Subtract<10, 3> // 7
937
+ * Subtract<5, 10> // 0 (clamped)
938
+ * ```
939
+ */
940
+ type Subtract<A extends number, B extends number> = NumberToArray<B> extends [...number[], ...NumberToArray<A>] ? 0 : NumberToArray<A> extends [...NumberToArray<B>, ...infer Rest] ? Rest['length'] : 0;
941
+ /**
942
+ * Range of numbers from start to end (inclusive)
943
+ * Note: Limited to small ranges due to TypeScript recursion limits
944
+ *
945
+ * @example
946
+ * ```ts
947
+ * Range<1, 5> // 1 | 2 | 3 | 4 | 5
948
+ * Range<0, 3> // 0 | 1 | 2 | 3
949
+ * ```
950
+ */
951
+ type Range<From extends number, To extends number, Acc extends number = From> = From extends To ? Acc : From extends To ? Acc : never;
952
+ /**
953
+ * Check if A is greater than B
954
+ *
955
+ * @example
956
+ * ```ts
957
+ * GreaterThan<5, 3> // true
958
+ * GreaterThan<3, 5> // false
959
+ * ```
960
+ */
961
+ type GreaterThan<A extends number, B extends number> = Subtract<A, B> extends 0 ? false : true;
962
+ /**
963
+ * Check if A is less than B
964
+ *
965
+ * @example
966
+ * ```ts
967
+ * LessThan<3, 5> // true
968
+ * LessThan<5, 3> // false
969
+ * ```
970
+ */
971
+ type LessThan<A extends number, B extends number> = Subtract<B, A> extends 0 ? false : true;
972
+ /**
973
+ * Maximum of two numbers
974
+ *
975
+ * @example
976
+ * ```ts
977
+ * Max<3, 5> // 5
978
+ * Max<5, 3> // 5
979
+ * ```
980
+ */
981
+ type Max<A extends number, B extends number> = GreaterThan<A, B> extends true ? A : B;
982
+ /**
983
+ * Minimum of two numbers
984
+ *
985
+ * @example
986
+ * ```ts
987
+ * Min<3, 5> // 3
988
+ * Min<5, 3> // 3
989
+ * ```
990
+ */
991
+ type Min<A extends number, B extends number> = LessThan<A, B> extends true ? A : B;
992
+ //#endregion
993
+ //#region src/path/index.d.ts
994
+ /**
995
+ * Enhanced path utilities with validation and array support
996
+ */
997
+ type Primitive = string | number | boolean | null | undefined | symbol | bigint | Date | RegExp;
998
+ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
999
+ /**
1000
+ * Check if a path exists in type T
1001
+ *
1002
+ * @example
1003
+ * ```ts
1004
+ * interface Obj {
1005
+ * a: {
1006
+ * b: string
1007
+ * }
1008
+ * }
1009
+ *
1010
+ * ValidPath<Obj, 'a.b'> // true
1011
+ * ValidPath<Obj, 'a.c'> // false
1012
+ * ```
1013
+ */
1014
+ type ValidPath<T, P extends string> = T extends Primitive ? P extends '' ? true : false : P extends '' ? true : P extends `${infer K}.${infer Rest}` ? K extends keyof T ? ValidPath<T[K], Rest> : false : P extends keyof T ? true : false;
1015
+ /**
1016
+ * Get all paths including array indices
1017
+ *
1018
+ * @example
1019
+ * ```ts
1020
+ * interface Users {
1021
+ * users: { name: string }[]
1022
+ * }
1023
+ *
1024
+ * ArrayPaths<Users>
1025
+ * // 'users' | `users.${number}` | `users.${number}.name`
1026
+ * ```
1027
+ */
1028
+ type ArrayPaths<T, D extends number = 10> = [D] extends [never] ? never : T extends Primitive ? never : T extends readonly (infer E)[] ? ArrayPaths<E, Prev[D]> extends infer P ? P extends string ? `${number}` | `${number}.${P}` : `${number}` : `${number}` : { [K in keyof T]: T[K] extends readonly unknown[] ? `${K & string}` | `${K & string}.${ArrayPaths<T[K], Prev[D]>}` : T[K] extends Primitive ? `${K & string}` : `${K & string}` | `${K & string}.${ArrayPaths<T[K], Prev[D]>}` }[keyof T];
1029
+ /**
1030
+ * Get leaf node paths only (paths to primitive values)
1031
+ *
1032
+ * @example
1033
+ * ```ts
1034
+ * interface Users {
1035
+ * users: { name: string, age: number }[]
1036
+ * }
1037
+ *
1038
+ * LeafPaths<Users>
1039
+ * // `users.${number}.name` | `users.${number}.age`
1040
+ * ```
1041
+ */
1042
+ type LeafPaths<T, D extends number = 10> = [D] extends [never] ? never : T extends Primitive ? never : T extends readonly (infer E)[] ? LeafPaths<E, Prev[D]> extends infer P ? P extends string ? `${number}.${P}` : never : never : { [K in keyof T]: T[K] extends Primitive ? `${K & string}` : LeafPaths<T[K], Prev[D]> extends never ? never : `${K & string}.${LeafPaths<T[K], Prev[D]>}` }[keyof T];
1043
+ /**
1044
+ * Get the length of a path (number of segments)
1045
+ *
1046
+ * @example
1047
+ * ```ts
1048
+ * PathLength<'a.b.c'> // 3
1049
+ * PathLength<'single'> // 1
1050
+ * ```
1051
+ */
1052
+ type PathLength<P extends string> = P extends '' ? 0 : P extends `${string}.${infer Rest}` ? Increment<PathLength<Rest>> : 1;
1053
+ type Increment<N extends number, Arr extends 0[] = []> = N extends Arr['length'] ? [...Arr, 0]['length'] : Increment<N, [...Arr, 0]>;
1054
+ /**
1055
+ * Get the parent path of a given path
1056
+ *
1057
+ * @example
1058
+ * ```ts
1059
+ * ParentPath<'a.b.c'> // 'a.b'
1060
+ * ParentPath<'a'> // ''
1061
+ * ```
1062
+ */
1063
+ type ParentPath<P extends string> = P extends `${infer Head}.${infer _}` ? Head : '';
1064
+ /**
1065
+ * Get the last segment of a path
1066
+ *
1067
+ * @example
1068
+ * ```ts
1069
+ * PathLeaf<'a.b.c'> // 'c'
1070
+ * PathLeaf<'a'> // 'a'
1071
+ * ```
1072
+ */
1073
+ type PathLeaf<P extends string> = P extends `${string}.${infer Tail}` ? PathLeaf<Tail> : P;
1074
+ //#endregion
1075
+ //#region src/record/index.d.ts
1076
+ /**
1077
+ * Record and object manipulation types
1078
+ */
1079
+ /**
1080
+ * Deep nullable - make all properties nullable
1081
+ *
1082
+ * @example
1083
+ * ```ts
1084
+ * DeepNullable<{ a: { b: string } }>
1085
+ * // { a: { b: string | null } }
1086
+ * ```
1087
+ */
1088
+ type DeepNullable<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? Map<DeepNullable<K>, DeepNullable<V>> : T extends Set<infer V> ? Set<DeepNullable<V>> : T extends readonly (infer E)[] ? DeepNullable<E>[] : T extends object ? { [K in keyof T]: DeepNullable<T[K]> | null } : T | null;
1089
+ /**
1090
+ * Deep optional - make all properties optional
1091
+ *
1092
+ * @example
1093
+ * ```ts
1094
+ * DeepOptional<{ a: { b: string } }>
1095
+ * // { a?: { b?: string } }
1096
+ * ```
1097
+ */
1098
+ type DeepOptional<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? Map<DeepOptional<K>, DeepOptional<V>> : T extends Set<infer V> ? Set<DeepOptional<V>> : T extends readonly (infer E)[] ? DeepOptional<E>[] : T extends object ? { [K in keyof T]?: DeepOptional<T[K]> } : T;
1099
+ /**
1100
+ * Immutable object - deep readonly alternative
1101
+ *
1102
+ * @example
1103
+ * ```ts
1104
+ * Immutable<{ a: { b: string[] } }>
1105
+ * // { readonly a: { readonly b: readonly string[] } }
1106
+ * ```
1107
+ */
1108
+ type Immutable<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? ReadonlyMap<Immutable<K>, Immutable<V>> : T extends Set<infer V> ? ReadonlySet<Immutable<V>> : T extends readonly (infer E)[] ? readonly Immutable<E>[] : T extends object ? { readonly [K in keyof T]: Immutable<T[K]> } : T;
1109
+ /**
1110
+ * Mutable object - deep mutable alternative
1111
+ *
1112
+ * @example
1113
+ * ```ts
1114
+ * Mutable<{ readonly a: { readonly b: readonly string[] } }>
1115
+ * // { a: { b: string[] } }
1116
+ * ```
1117
+ */
1118
+ type Mutable<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? Map<Mutable<K>, Mutable<V>> : T extends Set<infer V> ? Set<Mutable<V>> : T extends readonly (infer E)[] ? Mutable<E>[] : T extends object ? { -readonly [K in keyof T]: Mutable<T[K]> } : T;
1119
+ /**
1120
+ * Deep non-nullable - remove null and undefined from all properties
1121
+ *
1122
+ * @example
1123
+ * ```ts
1124
+ * DeepNonNullable<{ a: string | null; b: number | undefined }>
1125
+ * // { a: string; b: number }
1126
+ * ```
1127
+ */
1128
+ type DeepNonNullable<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? Map<DeepNonNullable<K>, DeepNonNullable<V>> : T extends Set<infer V> ? Set<DeepNonNullable<V>> : T extends readonly (infer E)[] ? DeepNonNullable<E>[] : T extends object ? { [K in keyof T]: DeepNonNullable<NonNullable<T[K]>> } : NonNullable<T>;
1129
+ /**
1130
+ * Exact type - ensure object has exactly these keys
1131
+ *
1132
+ * @example
1133
+ * ```ts
1134
+ * Exact<{ a: string }, { a: string }> // { a: string }
1135
+ * Exact<{ a: string }, { a: string, b: number }> // never
1136
+ * ```
1137
+ */
1138
+ type Exact<T, Shape> = T extends Shape ? Exclude<keyof T, keyof Shape> extends never ? T : never : never;
1139
+ /**
1140
+ * Make all properties non-optional
1141
+ *
1142
+ * @example
1143
+ * ```ts
1144
+ * Required<{ a?: string; b?: number }>
1145
+ * // { a: string; b: number }
1146
+ * ```
1147
+ */
1148
+ type Required$1<T> = { [K in keyof T]-?: T[K] };
1149
+ /**
1150
+ * Deep required with null/undefined handling
1151
+ *
1152
+ * @example
1153
+ * ```ts
1154
+ * DeepRequired<{ a?: { b?: string } }>
1155
+ * // { a: { b: string } }
1156
+ * ```
1157
+ */
1158
+ type DeepRequiredProperties<T> = T extends ((...args: any[]) => any) ? T : T extends Map<infer K, infer V> ? Map<DeepRequiredProperties<K>, DeepRequiredProperties<V>> : T extends Set<infer V> ? Set<DeepRequiredProperties<V>> : T extends readonly (infer E)[] ? DeepRequiredProperties<E>[] : T extends object ? { [K in keyof T]-?: DeepRequiredProperties<T[K]> } : T;
1159
+ /**
1160
+ * Object with at least the specified keys
1161
+ *
1162
+ * @example
1163
+ * ```ts
1164
+ * HasKeys<{ a: string; b: number }, 'a'>
1165
+ * // { a: string; b: number }
1166
+ * HasKeys<{ a: string }, 'b'>
1167
+ * // never
1168
+ * ```
1169
+ */
1170
+ type HasKeys<T, K extends keyof any> = K extends keyof T ? T : never;
1171
+ /**
1172
+ * Object with exactly the specified keys
1173
+ *
1174
+ * @example
1175
+ * ```ts
1176
+ * HasExactKeys<{ a: string }, 'a'>
1177
+ * // true
1178
+ * HasExactKeys<{ a: string; b: number }, 'a'>
1179
+ * // false
1180
+ * ```
1181
+ */
1182
+ type HasExactKeys<T, K extends keyof any> = keyof T extends K ? K extends keyof T ? true : false : false;
1183
+ //#endregion
1184
+ //#region src/template/index.d.ts
1185
+ /**
1186
+ * Template literal type utilities for string manipulation
1187
+ */
1188
+ /**
1189
+ * Replace all occurrences of a substring
1190
+ *
1191
+ * @example
1192
+ * ```ts
1193
+ * ReplaceAll<'hello world world', 'world', 'there'> // 'hello there there'
1194
+ * ReplaceAll<'aaa', 'a', 'b'> // 'bbb'
1195
+ * ```
1196
+ */
1197
+ type ReplaceAll<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${infer Before}${From}${infer After}` ? `${Before}${To}${ReplaceAll<After, From, To>}` : S;
1198
+ /**
1199
+ * Replace first occurrence of a substring
1200
+ *
1201
+ * @example
1202
+ * ```ts
1203
+ * Replace<'hello world world', 'world', 'there'> // 'hello there world'
1204
+ * ```
1205
+ */
1206
+ type Replace<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${infer Before}${From}${infer After}` ? `${Before}${To}${After}` : S;
1207
+ /**
1208
+ * Trim whitespace from both ends
1209
+ *
1210
+ * @example
1211
+ * ```ts
1212
+ * Trim<' hello '> // 'hello'
1213
+ * Trim<'\n\ttext\n'> // 'text'
1214
+ * ```
1215
+ */
1216
+ type Trim<S extends string> = TrimLeft<TrimRight<S>>;
1217
+ /**
1218
+ * Trim whitespace from left
1219
+ *
1220
+ * @example
1221
+ * ```ts
1222
+ * TrimLeft<' hello'> // 'hello'
1223
+ * ```
1224
+ */
1225
+ type TrimLeft<S extends string> = S extends ` ${infer Rest}` ? TrimLeft<Rest> : S extends `\n${infer Rest}` ? TrimLeft<Rest> : S extends `\t${infer Rest}` ? TrimLeft<Rest> : S extends `\r${infer Rest}` ? TrimLeft<Rest> : S;
1226
+ /**
1227
+ * Trim whitespace from right
1228
+ *
1229
+ * @example
1230
+ * ```ts
1231
+ * TrimRight<'hello '> // 'hello'
1232
+ * ```
1233
+ */
1234
+ type TrimRight<S extends string> = S extends `${infer Rest} ` ? TrimRight<Rest> : S extends `${infer Rest}\n` ? TrimRight<Rest> : S extends `${infer Rest}\t` ? TrimRight<Rest> : S extends `${infer Rest}\r` ? TrimRight<Rest> : S;
1235
+ /**
1236
+ * Convert string to array of characters
1237
+ *
1238
+ * @example
1239
+ * ```ts
1240
+ * StringToArray<'abc'> // ['a', 'b', 'c']
1241
+ * ```
1242
+ */
1243
+ type StringToArray<S extends string, Acc extends string[] = []> = S extends `${infer First}${infer Rest}` ? StringToArray<Rest, [...Acc, First]> : Acc;
1244
+ /**
1245
+ * Capitalize all words in a string
1246
+ *
1247
+ * @example
1248
+ * ```ts
1249
+ * CapitalizeAll<'hello world'> // 'Hello World'
1250
+ * ```
1251
+ */
1252
+ type CapitalizeAll<S extends string> = S extends `${infer First} ${infer Rest}` ? `${Capitalize<First>} ${CapitalizeAll<Rest>}` : S extends `${infer First}` ? Capitalize<First> : S;
1253
+ /**
1254
+ * Uncapitalize all words in a string
1255
+ *
1256
+ * @example
1257
+ * ```ts
1258
+ * UncapitalizeAll<'Hello World'> // 'hello world'
1259
+ * ```
1260
+ */
1261
+ type UncapitalizeAll<S extends string> = S extends `${infer First} ${infer Rest}` ? `${Uncapitalize<First>} ${UncapitalizeAll<Rest>}` : S extends `${infer First}` ? Uncapitalize<First> : S;
1262
+ /**
1263
+ * Check if string starts with a prefix
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * StartsWith<'hello world', 'hello'> // true
1268
+ * StartsWith<'hello world', 'world'> // false
1269
+ * ```
1270
+ */
1271
+ type StartsWith<S extends string, P extends string> = S extends `${P}${any}` ? true : false;
1272
+ /**
1273
+ * Check if string ends with a suffix
1274
+ *
1275
+ * @example
1276
+ * ```ts
1277
+ * EndsWith<'hello world', 'world'> // true
1278
+ * EndsWith<'hello world', 'hello'> // false
1279
+ * ```
1280
+ */
1281
+ type EndsWith<S extends string, P extends string> = S extends `${any}${P}` ? true : false;
1282
+ /**
1283
+ * Get string length at type level
1284
+ *
1285
+ * @example
1286
+ * ```ts
1287
+ * StringLength<'hello'> // 5
1288
+ * ```
1289
+ */
1290
+ type StringLength<S extends string, Acc extends 0[] = []> = S extends `${string}${infer Rest}` ? StringLength<Rest, [...Acc, 0]> : Acc['length'];
1291
+ /**
1292
+ * Repeat a string N times
1293
+ *
1294
+ * @example
1295
+ * ```ts
1296
+ * Repeat<'ab', 3> // 'ababab'
1297
+ * ```
1298
+ */
1299
+ type Repeat<S extends string, N extends number, Acc extends string = '', Count extends 0[] = []> = Count['length'] extends N ? Acc : Repeat<S, N, `${Acc}${S}`, [...Count, 0]>;
1300
+ /**
1301
+ * Pad string on the left
1302
+ *
1303
+ * @example
1304
+ * ```ts
1305
+ * PadStart<'5', 3, '0'> // '005'
1306
+ * ```
1307
+ */
1308
+ type PadStart<S extends string, N extends number, P extends string = ' '> = StringLength<S> extends N ? S : N extends number ? `${P}${PadStart<S, Decrement<N>, P>}` : S;
1309
+ /**
1310
+ * Pad string on the right
1311
+ *
1312
+ * @example
1313
+ * ```ts
1314
+ * PadEnd<'5', 3, '0'> // '500'
1315
+ * ```
1316
+ */
1317
+ type PadEnd<S extends string, N extends number, P extends string = ' '> = StringLength<S> extends N ? S : N extends number ? `${PadEnd<S, Decrement<N>, P>}${P}` : S;
1318
+ type Decrement<N extends number, Acc extends 0[] = []> = N extends 0 ? 0 : [...Acc, 0]['length'] extends N ? Acc['length'] : Decrement<N, [...Acc, 0]>;
1319
+ //#endregion
1320
+ export { Add, And, AppendParameter, ArrayElement, ArrayPaths, Assert, AsyncReturnType, AtLeastOne, Awaited, Brand, BrandedNumber, BrandedString, CamelCase, CamelCaseKeys, CapitalizeAll, DataOnly, Dec, DeepMutable, DeepNonNullable, DeepNullable, DeepOmit, DeepOmitPaths, DeepOptional, DeepPartial, DeepPick, DeepPickPaths, DeepReadonly, DeepRequired, DeepRequiredProperties, EndsWith, Exact, Exclusive, FilterKeys, FirstParameter, Flatten, FunctionKeys, FunctionOnly, GreaterThan, HasExactKeys, HasKeys, Head, If, Immutable, Inc, Init, IsAny, IsArray, IsAsyncFunction, IsEmptyTuple, IsEqual, IsFunction, IsNever, IsTuple, IsUnknown, Keys, KeysByValueType, Last, LeafPaths, LessThan, Literal, LiteralBoolean, LiteralNumber, LiteralString, LoosePartial, Max, Maybe, Merge, Min, Mutable, NoNullish, NonFunctionKeys, NonNullable$1 as NonNullable, Not, NthParameter, Nullable, OmitPartial, OmitRequired, OmitThisParameter, Optional, OptionalKeys, OptionalParameters, Or, PadEnd, PadStart, Parameters, ParentPath, PascalCaseKeys, PathLeaf, PathLength, PathValue, Paths, PickPartial, PickRequired, PrefixKeys, PrependParameter, Range, ReadonlyKeys, RenameKeys, Repeat, Replace, ReplaceAll, Required$1 as Required, RequiredKeys, ReturnType, Reverse, SnakeCase, SnakeCaseKeys, SplitPath, StartsWith, StrictExclude, StrictExtract, StringLength, StringToArray, Subtract, SuffixKeys, Tail$1 as Tail, ThisParameterType, Trim, TrimLeft, TrimRight, TupleLength, Unbrand, UncapitalizeAll, UnionToIntersection, UnionToTuple, ValidPath, ValueOf, WritableKeys };