@rzl-zone/utils-js 3.3.0 → 3.4.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.
@@ -1,3345 +0,0 @@
1
- import{A as And,b as Or,O as OrArr,a as AndArr}from'../or-C6qzKt2I.js';import{I as IsStringLiteral,P as ParseNumber,a as IsNegative,N as Negate,A as Abs,b as IsFloat,c as IsUnknown,d as IsNegativeInteger,S as Split,e as IsInteger,R as Repeat,f as Push,g as IfNegative,h as IsPositive,i as IsEven,j as IsReadonlyArray,k as IfPositive}from'../is-array-BJeHxPM3.js';export{C as CharAt,E as Even,q as EvenDigit,F as Float,r as IfEven,s as IfFloat,t as IfInteger,u as IfNegativeFloat,v as IfNegativeInteger,w as IfOdd,x as IfPositiveFloat,y as IfPositiveInteger,Y as IfUnknown,z as Integer,l as IsArray,m as IsMutableArray,B as IsNegativeFloat,D as IsOdd,G as IsPositiveFloat,H as IsPositiveInteger,J as IsScientificNumber,M as Mutable,n as MutableExcept,o as MutableOnly,p as MutableOptions,K as Negative,L as NegativeFloat,O as NegativeInteger,Q as Odd,T as OddDigit,U as ParseScientificNumber,V as Positive,W as PositiveFloat,X as PositiveInteger,Z as UnknownifyProperties,_ as UnknownifyPropertiesOptions}from'../is-array-BJeHxPM3.js';import{a as IsEmptyString,b as IfEmptyString,T as Trim,A as AnyString}from'../string-B1jlOnws.js';export{E as EmptyString,d as IfNonEmptyString,I as IfNot,e as IsNonEmptyString,N as NonEmptyString,f as TrimLeft,g as TrimRight,h as TrimsLower,i as TrimsUpper,W as Whitespace,c as WordSeparator}from'../string-B1jlOnws.js';import{I as IsAny}from'../any-v4TsK9ES.js';export{A as AnifyProperties,a as AnifyPropertiesOptions,b as IfAny}from'../any-v4TsK9ES.js';import{A as AnyFunction,T as TypedArray,P as Prettify,a as PrettifyOptions,D as DefaultPrettifyOptions}from'../prettify-3o8_Kw6b.js';export{g as AnObjectNonArray,B as BoxedPrimitivesTypes,h as DataTypes,i as DeepReplaceType,j as IntlObjects,I as IsArrayOrTuple,b as IsConstructor,c as IsFunction,d as IsPrimitive,e as IsRealPrimitive,N as NonPlainObject,f as Primitive,W as WebApiObjects}from'../prettify-3o8_Kw6b.js';import{I as IfExtends,N as Not,a as NotExtends,b as IsEmptyArray,P as Pop,E as Extends,c as ExtendsArr,d as IfEmptyArray}from'../extends-DtdRjDyU.js';export{A as Arrayable,e as EmptyArray,G as GetArrayElementType,f as IfNonEmptyArray,i as IfNotExtends,g as IsNonEmptyArray,M as MutableArray,h as NonEmptyArray,j as PopOptions}from'../extends-DtdRjDyU.js';export{F as FixNeverArrayRecursive,N as NormalizeEmptyArraysRecursive,R as RemoveEmptyArrayElements}from'../arrays-normalize-recursive-BqmVuFlD.js';import{I as If}from'../if-ChM35c_q.js';import{I as IsNever,a as IfNever}from'../never-D89PbPh5.js';export{N as NeverifyProperties,b as NeverifyPropertiesOptions}from'../never-D89PbPh5.js';export{E as ExtractStrict,O as OmitStrict,a as OverrideTypes}from'../override-CL2olHE5.js';import{N as NonUndefined}from'../nils-CO8zLHSB.js';export{K as KeepNil,a as KeepNull,b as KeepUndef,c as Nilable,d as NonNil,e as NonNull,g as NullToUndefined,f as Nullable,h as Nullish,U as Undefinedable}from'../nils-CO8zLHSB.js';export{N as NumberRangeUnion}from'../NumberRangeUnion-B6bhM2s7.js';export{P as PickStrict}from'../pick-BSMX6Xe2.js';export{A as Awaitable,C as CustomPromiseType}from'../promises-LU7K00H0.js';
2
- /** @private ***types for {@link AreAnagrams}.*** */
3
- type _AreAnagrams<Str1 extends string,Str2 extends string>=IsEmptyString<Str1>extends true?IsEmptyString<Str2>extends true?true:false:Str1 extends`${infer First extends string}${infer Rest1 extends string}`?Str2 extends`${infer Prev extends string}${First}${infer Rest2 extends string}`?_AreAnagrams<Rest1,`${Prev}${Rest2}`>:false:never;
4
- /** -------------------------------------------------------
5
- * * ***Utility Type: `AreAnagrams`.***
6
- * -------------------------------------------------------
7
- * **Determines whether two string literal types are ***anagrams*** of each other.**
8
- * - **Behavior:**
9
- * - Returns `true` if both strings contain exactly the same characters in
10
- * any order.
11
- * - Returns `false` otherwise.
12
- * @template Str1 - The first string literal.
13
- * @template Str2 - The second string literal.
14
- * @example
15
- * ```ts
16
- * type Case1 = AreAnagrams<"name", "eman">;
17
- * // ➔ true
18
- * type Case2 = AreAnagrams<"name", "emand">;
19
- * // ➔ false
20
- * type Case3 = AreAnagrams<"abc", "cba">;
21
- * // ➔ true
22
- * type Case4 = AreAnagrams<"abc", "abcd">;
23
- * // ➔ false
24
- * ```
25
- */
26
- type AreAnagrams<Str1 extends string,Str2 extends string>=And<IsStringLiteral<Str1>,IsStringLiteral<Str2>>extends true?_AreAnagrams<Str1,Str2>:false;
27
- /** --------------------------------------------------
28
- * * ***Utility Type: `ArgumentTypes`.***
29
- * --------------------------------------------------
30
- * **Extracts the **argument types** of a given function type `F`.**
31
- * - ✅ Useful when you need to infer or reuse the parameter types
32
- * from an existing function signature.
33
- * @template F - A function type from which to extract argument types.
34
- * @example
35
- * ```ts
36
- * type Args = ArgumentTypes<(a: number, b: string) => void>;
37
- * // ➔ [number, string]
38
- * ```
39
- */
40
- type ArgumentTypes<F extends AnyFunction>=F extends(...args:infer A)=>any?A:never;
41
- /** -------------------------------------------------------
42
- * * ***Utility Type: `ArrayElementType`.***
43
- * -------------------------------------------------------
44
- * **A type-level utility that extracts the element type of an array.**
45
- * - **Behavior:**
46
- * - Works with both mutable and readonly arrays.
47
- * - If `T` is not an array, resolves to `never`.
48
- * @template T - The array type to extract the element type from.
49
- * @example
50
- * ```ts
51
- * type A = ArrayElementType<string[]>;
52
- * // ➔ string
53
- * type B = ArrayElementType<readonly ("a" | "b")[]>;
54
- * // ➔ "a" | "b"
55
- * type C = ArrayElementType<number>;
56
- * // ➔ never
57
- * ```
58
- */
59
- type ArrayElementType<T extends readonly unknown[]>=T extends Readonly<Array<infer Item>>?Item:never;
60
- /** ---------------------------------------------------------------------------
61
- * * ***Type Options for {@link LastCharacter | `LastCharacter`}.***
62
- * ---------------------------------------------------------------------------
63
- */
64
- type LastCharacterOptions={includeRest:boolean;};type _LastCharacter<T extends string,Options extends LastCharacterOptions={includeRest:false;},Previous extends string="">=string extends T?string:T extends`${infer First}${infer Rest}`?IsEmptyString<Rest>extends true?If<Options["includeRest"],[First,Previous],First>:_LastCharacter<Rest,Options,`${Previous}${First}`>:T;
65
- /** -------------------------------------------------------
66
- * * ***Utility Type: `LastCharacter`.***
67
- * -------------------------------------------------------
68
- * **Accepts a string argument and returns its last character.**
69
- * - If the `includeRest` option is `true`, returns the last character and the rest of the string in the format: `[last, rest]`.
70
- * @template T - The string to get the last character from.
71
- * @template Options - Options to include the rest of the string.
72
- * @example
73
- * type Case1 = LastCharacter<'abc'>;
74
- * // ➔ 'c'
75
- * type Case2 = LastCharacter<'abc', { includeRest: true }>;
76
- * // ➔ ['c', 'ab']
77
- */
78
- type LastCharacter<T extends string,Options extends LastCharacterOptions={includeRest:false;}>=IfExtends<Options,LastCharacterOptions,_LastCharacter<T,Options>,_LastCharacter<T>>;
79
- /** -------------------------------------------------------
80
- * * ***Utility Type: `Stringify`.***
81
- * -------------------------------------------------------
82
- * **Converts a value of type `number`, `boolean`, `string`, `bigint`, `undefined`, or `null` into a string literal type.**
83
- * - **Behavior:**
84
- * - `number` ➔ string representation (e.g., `123` ➔ `"123"`)
85
- * - `boolean` ➔ `"true"` or `"false"`
86
- * - `string` ➔ itself
87
- * - `bigint` ➔ string representation with `"n"` suffix (e.g., `123n` ➔ `"123n"`)
88
- * - `undefined` ➔ `"undefined"`
89
- * - `null` ➔ `"null"`
90
- * - Other types ➔ `never`
91
- * @template T - The value type to stringify.
92
- * @example
93
- * ```ts
94
- * // Boolean
95
- * type Result1 = Stringify<true>;
96
- * // ➔ "true"
97
- *
98
- * // Number
99
- * type Result2 = Stringify<123>;
100
- * // ➔ "123"
101
- *
102
- * // BigInt
103
- * type Result3 = Stringify<123n>;
104
- * // ➔ "123n"
105
- *
106
- * // String
107
- * type Result4 = Stringify<"hello">;
108
- * // ➔ "hello"
109
- *
110
- * // Undefined
111
- * type Result5 = Stringify<undefined>;
112
- * // ➔ "undefined"
113
- *
114
- * // Null
115
- * type Result6 = Stringify<null>;
116
- * // ➔ "null"
117
- *
118
- * // Other type
119
- * type Result7 = Stringify<{}>;
120
- * // ➔ never
121
- * ```
122
- */
123
- type Stringify<T>=T extends number|boolean|string|bigint|undefined|null?T extends bigint?`${T}n`:`${T}`:never;type DecrementMap=[-1,0,1,2,3,4,5,6,7,8];type NegativeCarryMap={"-1":9;};
124
- /** -------------------------------------------------------
125
- * * ***Internal Utility Type: `_Decrement (Internal / Deprecated)`***
126
- * -------------------------------------------------------
127
- * **Internal type-level utility to decrement a numeric string by 1.**
128
- * - **⚠️ Deprecated:**
129
- * - Do **not** use this directly.
130
- * - Use the public {@link Decrement | **`Decrement`**} type instead.
131
- * - Processes the string recursively digit by digit.
132
- * - Handles borrow/carry using internal `DecrementMap` and `NegativeCarryMap`.
133
- * @template Number - The numeric string to decrement.
134
- * @template Result - (Internal) Accumulator used during recursion.
135
- * @deprecated Use {@link Decrement | **`Decrement`**} instead.
136
- * @example
137
- * ```ts
138
- * // ❌ Avoid using _Decrement directly
139
- * type R1 = _Decrement<"23">;
140
- *
141
- * // ✅ Use Decrement instead
142
- * type R2 = Decrement<"23">; // ➔ 22
143
- * ```
144
- */
145
- type _Decrement<Number extends string,Result extends string="">=Number extends""?ParseNumber<Result>:ParseNumber<LastCharacter<Number>>extends infer LastDigit extends number?DecrementMap[LastDigit] extends infer Decremented extends number?Number extends`${infer Rest}${LastDigit}`?`${Decremented}`extends keyof NegativeCarryMap?_Decrement<Rest,`${NegativeCarryMap[`${Decremented}`]}${Result}`>:`${Rest}${Decremented}${Result}`extends infer FinalResult extends string?ParseNumber<FinalResult extends`0${infer FinalResultWithoutLeadingZero extends string}`?FinalResultWithoutLeadingZero extends""?FinalResult:FinalResultWithoutLeadingZero:FinalResult>:never:never:never:never;type _DecrementNegativeOrZero<T extends number>=_Increment<Stringify<T>>extends infer PositiveDecrementResult extends number?PositiveDecrementResult extends 0?PositiveDecrementResult:Negate<PositiveDecrementResult>:never;
146
- /** -------------------------------------------------------
147
- * * ***Utility Type: `Decrement`.***
148
- * --------------------------------------------------------
149
- * **A type-level utility that returns the decremented value of an integer.**
150
- * - Works for numbers in the range `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
151
- * @template T - The number type to decrement.
152
- * @example
153
- * ```ts
154
- * type A = Decrement<6>; // ➔ 5
155
- * type B = Decrement<0>; // ➔ -1
156
- * type C = Decrement<-6>; // ➔ -7
157
- * type D = Decrement<123>; // ➔ 122
158
- * type E = Decrement<-1>; // ➔ -2
159
- * ```
160
- */
161
- type Decrement<T extends number>=IsNegative<T>extends true?_DecrementNegativeOrZero<Abs<T>>:T extends 0?_DecrementNegativeOrZero<T>:_Decrement<Stringify<T>>;type IncrementMap=[1,2,3,4,5,6,7,8,9,10];type LastDigitMap={10:0;};
162
- /** -------------------------------------------------------
163
- * * ***Internal Utility Type: `_Increment (Internal / Deprecated)`***
164
- * -------------------------------------------------------
165
- * **Internal type-level utility to increment a numeric string by 1.**
166
- * - **⚠️ Deprecated:**
167
- * - Do **not** use this directly.
168
- * - Use the public {@link Increment | **`Increment`**} type instead.
169
- * - Processes the string recursively digit by digit.
170
- * - Handles carry-over using internal `IncrementMap` and `LastDigitMap`.
171
- * @template Number - The numeric string to increment.
172
- * @template Result - (Internal) Accumulator used during recursion.
173
- * @deprecated Use {@link Increment | **`Increment`**} instead.
174
- * @example
175
- * ```ts
176
- * // ❌ Avoid using _Increment directly
177
- * type R1 = _Increment<"23">;
178
- *
179
- * // ✅ Use Increment instead
180
- * type R2 = Increment<"23">; // ➔ 24
181
- * ```
182
- */
183
- type _Increment<Number extends string,Result extends string="">=IsEmptyString<Number>extends true?ParseNumber<`1${Result}`>:LastCharacter<Number>extends`${infer LastDigit extends number}`?IncrementMap[LastDigit] extends infer Incremented extends number?Number extends`${infer Rest}${LastDigit}`?Incremented extends keyof LastDigitMap?_Increment<Rest,`${LastDigitMap[Incremented]}${Result}`>:ParseNumber<`${Rest}${Incremented}${Result}`>:never:never:never;
184
- /** -------------------------------------------------------
185
- * * ***Utility Type: `Increment`.***
186
- * -------------------------------------------------------
187
- * **Accepts an integer and returns the incremented value of it.**
188
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`
189
- * @template T - The input number to increment.
190
- * @example
191
- * ```ts
192
- * type Case1 = Increment<1>; // ➔ 2
193
- * type Case2 = Increment<-10>; // ➔ -9
194
- * ```
195
- */
196
- type Increment<T extends number>=IsNegative<T>extends true?_Decrement<Stringify<Abs<T>>>extends infer NegativeIncrementResult extends number?NegativeIncrementResult extends 0?NegativeIncrementResult:Negate<NegativeIncrementResult>:never:_Increment<Stringify<T>>;
197
- /** -------------------------------------------------------
198
- * * ***Utility Type: `GetFloatNumberParts`.***
199
- * -------------------------------------------------------
200
- * **Returns a tuple of the **whole** and **fraction** parts of a float number `T`.**
201
- * - **Behavior:**
202
- * - Only works for **float numbers** (i.e., numbers with a fractional part):
203
- * - If `T` is not a float, the result is `never`.
204
- * - Preserves the sign on the whole part (e.g. `-12.25` ➔ `[-12, 25]`).
205
- * - For values like `-0.x`, the TypeScript will normalizes `-0` to `0`,
206
- * so the result will be `[0, ...]`.
207
- * @template T - A float number type.
208
- * @example
209
- * ```ts
210
- * type A = GetFloatNumberParts<12.25>; // ➔ [12, 25]
211
- * type B = GetFloatNumberParts<-12.25>; // ➔ [-12, 25]
212
- * type C = GetFloatNumberParts<3.1415>; // ➔ [3, 1415]
213
- * type D = GetFloatNumberParts<-0.75>; // ➔ [0, 75] (`-0` normalized to `0`)
214
- * type E = GetFloatNumberParts<42>; // ➔ never (not a float)
215
- * ```
216
- */
217
- type GetFloatNumberParts<T extends number>=IsFloat<T>extends true?`${T}`extends`${infer Whole extends number}.${infer Fraction extends number}`?[IsNegative<T>extends true?Whole:Whole,Fraction]:never:never;
218
- /** -------------------------------------------------------
219
- * * ***Utility Type: `Ceil`.***
220
- * -------------------------------------------------------
221
- * **A type-level utility that computes the **mathematical ceiling**
222
- * of a numeric literal type `T`, type version of `Math.ceil()`.**
223
- * - **Behavior:**
224
- * - If `T` is an integer, it returns `T` unchanged.
225
- * - If `T` is a positive float, it rounds up to the nearest integer.
226
- * - If `T` is a negative float, it rounds up toward zero.
227
- * @template T - A number literal type.
228
- * @example
229
- * ```ts
230
- * type A = Ceil<1.2>; // ➔ 2
231
- * type B = Ceil<1.9>; // ➔ 2
232
- * type C = Ceil<5>; // ➔ 5
233
- * type D = Ceil<-1.2>; // ➔ -1
234
- * type E = Ceil<-1.9>; // ➔ -1
235
- * type F = Ceil<-5>; // ➔ -5
236
- * ```
237
- */
238
- type Ceil<T extends number>=IsFloat<T>extends true?GetFloatNumberParts<T>extends [infer Whole extends number,unknown]?IsNegative<T>extends true?Negate<Whole>:Increment<Whole>:never:T;
239
- /** -------------------------------------------------------
240
- * * ***Utility Type: `ColorCssNamed`.***
241
- * -------------------------------------------------------
242
- * **Represents a **named CSS color keyword**, including `transparent`.**
243
- * @description
244
- * This type includes all standard color names defined in the CSS Color Module Level 4
245
- * specification, and ensures type safety for string values in strongly typed UI libraries,
246
- * themes, or design systems.
247
- * - **Behavior:**
248
- * - Only recognized, browser-supported named colors are allowed.
249
- * @see https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
250
- * @see https://drafts.csswg.org/css-color-4/#named-colors
251
- * @example
252
- * ```ts
253
- * const textColor1: ColorCssNamed = "rebeccapurple"; // ➔ ✅ valid
254
- * const textColor2: ColorCssNamed = "navy"; // ➔ ✅ valid
255
- * const textColor3: ColorCssNamed = "superblue"; // ➔ ❌ Type error
256
- *
257
- * // Usage in a theme object
258
- * const theme: Record<string, ColorCssNamed> = {
259
- * primary: "blue",
260
- * secondary: "goldenrod",
261
- * highlight: "transparent",
262
- * };
263
- * ```
264
- */
265
- type ColorCssNamed="aliceblue"|"antiquewhite"|"aqua"|"aquamarine"|"azure"|"beige"|"bisque"|"black"|"blanchedalmond"|"blue"|"blueviolet"|"brown"|"burlywood"|"cadetblue"|"chartreuse"|"chocolate"|"coral"|"cornflowerblue"|"cornsilk"|"crimson"|"cyan"|"darkblue"|"darkcyan"|"darkgoldenrod"|"darkgray"|"darkgreen"|"darkgrey"|"darkkhaki"|"darkmagenta"|"darkolivegreen"|"darkorange"|"darkorchid"|"darkred"|"darksalmon"|"darkseagreen"|"darkslateblue"|"darkslategray"|"darkslategrey"|"darkturquoise"|"darkviolet"|"deeppink"|"deepskyblue"|"dimgray"|"dimgrey"|"dodgerblue"|"firebrick"|"floralwhite"|"forestgreen"|"fuchsia"|"gainsboro"|"ghostwhite"|"gold"|"goldenrod"|"gray"|"green"|"greenyellow"|"grey"|"honeydew"|"hotpink"|"indianred"|"indigo"|"ivory"|"khaki"|"lavender"|"lavenderblush"|"lawngreen"|"lemonchiffon"|"lightblue"|"lightcoral"|"lightcyan"|"lightgoldenrodyellow"|"lightgray"|"lightgreen"|"lightgrey"|"lightpink"|"lightsalmon"|"lightseagreen"|"lightskyblue"|"lightslategray"|"lightslategrey"|"lightsteelblue"|"lightyellow"|"lime"|"limegreen"|"linen"|"magenta"|"maroon"|"mediumaquamarine"|"mediumblue"|"mediumorchid"|"mediumpurple"|"mediumseagreen"|"mediumslateblue"|"mediumspringgreen"|"mediumturquoise"|"mediumvioletred"|"midnightblue"|"mintcream"|"mistyrose"|"moccasin"|"navajowhite"|"navy"|"oldlace"|"olive"|"olivedrab"|"orange"|"orangered"|"orchid"|"palegoldenrod"|"palegreen"|"paleturquoise"|"palevioletred"|"papayawhip"|"peachpuff"|"peru"|"pink"|"plum"|"powderblue"|"purple"|"rebeccapurple"|"red"|"rosybrown"|"royalblue"|"saddlebrown"|"salmon"|"sandybrown"|"seagreen"|"seashell"|"sienna"|"silver"|"skyblue"|"slateblue"|"slategray"|"slategrey"|"snow"|"springgreen"|"steelblue"|"tan"|"teal"|"thistle"|"tomato"|"transparent"|"turquoise"|"violet"|"wheat"|"white"|"whitesmoke"|"yellow"|"yellowgreen";
266
- /** -------------------------------------------------------
267
- * * ***Utility Type: `IsEqual`.***
268
- * -------------------------------------------------------
269
- * **A type-level utility that returns a boolean indicating
270
- * whether the two types are ***equal***.**
271
- * @template T - The first type to compare.
272
- * @template U - The second type to compare.
273
- * @example
274
- * ```ts
275
- * type A = IsEqual<string, string>;
276
- * // ➔ true
277
- * type B = IsEqual<1, 4>;
278
- * // ➔ false
279
- * type C = IsEqual<true, false>;
280
- * // ➔ false
281
- * type D = IsEqual<any, any>;
282
- * // ➔ true
283
- * ```
284
- */
285
- type IsEqual<T,U>=(<F>()=>F extends T?1:2)extends<F>()=>F extends U?1:2?true:false;
286
- /** -------------------------------------------------------
287
- * * ***Utility Type: `IsNotEqual`.***
288
- * -------------------------------------------------------
289
- * **A type-level utility that returns a boolean indicating
290
- * whether the two types are ***not equal***.**
291
- * @template T - The first type to compare.
292
- * @template U - The second type to compare.
293
- * @example
294
- * ```ts
295
- * type A = IsNotEqual<1, 4>;
296
- * // ➔ true
297
- * type B = IsNotEqual<string, string>;
298
- * // ➔ false
299
- * ```
300
- */
301
- type IsNotEqual<T,U>=Not<IsEqual<T,U>>;
302
- /** -------------------------------------------------------
303
- * * ***Utility Type: `IfEqual`.***
304
- * -------------------------------------------------------
305
- * - **Conditional:**
306
- * - Selects one of two branches depending on whether `T` and `U` are ***equal***.
307
- * - Defaults: `IfTrue = true`, `IfFalse = false`.
308
- * @template T - The first type to compare.
309
- * @template U - The second type to compare.
310
- * @template IfTrue - The branch type if condition is met. (default: `true`)
311
- * @template IfFalse - The branch type if condition is not met. (default: `false`)
312
- * @example
313
- * ```ts
314
- * type A = IfEqual<string, string, "valid">; // ➔ "valid"
315
- * type B = IfEqual<1, 4, "valid", "invalid">; // ➔ "invalid"
316
- * ```
317
- */
318
- type IfEqual<T,U,IfTrue=true,IfFalse=false>=If<IsEqual<T,U>,IfTrue,IfFalse>;
319
- /** -------------------------------------------------------
320
- * * ***Utility Type: `IfNotEqual`.***
321
- * -------------------------------------------------------
322
- * - **Conditional:**
323
- * - Selects one of two branches depending on whether `T` and `U` are ***not equal***.
324
- * - Defaults: `IfTrue = true`, `IfFalse = false`.
325
- * @template T - The first type to compare.
326
- * @template U - The second type to compare.
327
- * @template IfTrue - The branch type if condition is met. (default: `true`)
328
- * @template IfFalse - The branch type if condition is not met. (default: `false`)
329
- * @example
330
- * ```ts
331
- * type A = IfNotEqual<1, 4, "valid">;
332
- * // ➔ "valid"
333
- * type B = IfNotEqual<string, string, "valid", "invalid">;
334
- * // ➔ "invalid"
335
- * ```
336
- */
337
- type IfNotEqual<T,U,IfTrue=true,IfFalse=false>=If<IsNotEqual<T,U>,IfTrue,IfFalse>;
338
- /** -------------------------------------------------------
339
- * * ***Utility Type: `IsExactly`.***
340
- * -------------------------------------------------------
341
- * **A strict equality check between two types `A` and `B`
342
- * that does **not** collapse when one of them is `any`.**
343
- * - **Behavior:**
344
- * - Returns `true` only if `A` and `B` are **mutually assignable**.
345
- * - Returns `false` if either `A` or `B` is `any`.
346
- * @template A - The first type to compare.
347
- * @template B - The second type to compare.
348
- * @example
349
- * ```ts
350
- * type A = IsExactly<string, string>; // ➔ true
351
- * type B = IsExactly<string, any>; // ➔ false
352
- * type C = IsExactly<42, number>; // ➔ false
353
- * type D = IsExactly<never, never>; // ➔ true
354
- * type E = IsExactly<any, any>; // ➔ false
355
- * ```
356
- */
357
- type IsExactly<A,B>=IsAny<A>extends true?false:IsAny<B>extends true?false:(<T>()=>T extends A?1:2)extends<T>()=>T extends B?1:2?(<T>()=>T extends B?1:2)extends<T>()=>T extends A?1:2?true:false:false;
358
- /** -------------------------------------------------------
359
- * * ***Utility Type: `IsGeneralArray`.***
360
- * -------------------------------------------------------
361
- * **Checks if `T` is a **general array type** (`X[]` or `ReadonlyArray<X>`)
362
- * instead of a tuple literal.**
363
- * - **Behavior:**
364
- * - Returns `true` for `string[]`, `(number | boolean)[]`, `any[]`, etc.
365
- * - Returns `false` for tuples like `[]`, `[1, 2, 3]`, or `[string, number]`.
366
- * @template T - The type to check.
367
- * @example
368
- * ```ts
369
- * type A = IsGeneralArray<string[]>; // ➔ true
370
- * type B = IsGeneralArray<[]>; // ➔ false
371
- * type C = IsGeneralArray<[1, 2, 3]>; // ➔ false
372
- * type D = IsGeneralArray<ReadonlyArray<number>>; // ➔ true
373
- * ```
374
- */
375
- type IsGeneralArray<T>=T extends readonly unknown[]?number extends T["length"]?true:false:false;
376
- /** -------------------------------------------------------
377
- * * ***Utility Type: `IsBaseType`.***
378
- * -------------------------------------------------------
379
- * **Determines whether a type `T` is considered a **base / keyword / built-in type**
380
- * rather than a literal, tuple, or specific instance.**
381
- * - **Behavior:**
382
- * - ***✅ Considered base types:***
383
- * - Special keywords: `any`, `unknown`, `never`, `null`, `undefined`, `void`
384
- * - Primitive keywords: `string`, `number`, `boolean`, `bigint`, `symbol`
385
- * - Function keyword `Function` and alias `AnyFunction`
386
- * - General arrays (`X[]`, `ReadonlyArray<X>`) and `TypedArray`
387
- * - Common built-ins: `Date`, `RegExp`, `Error`
388
- * - Generic containers: `Promise<any>`, `Map<any,any>`, `WeakMap<object,any>`, `Set<any>`, `WeakSet<object>`
389
- * - Buffers & views: `ArrayBuffer`, `SharedArrayBuffer`, `DataView`
390
- * - `object` keyword and `{}` (empty object type)
391
- * - ***❌ Not considered base types:***
392
- * - Literal values (`"foo"`, `123`, `true`)
393
- * - Union literals (`"a" | "b"`)
394
- * - Tuples (`[1, 2, 3]`, `[]`)
395
- * - Specific object shapes (`{ a: 1 }`, `{ x: string }`)
396
- * - Functions with explicit structure (`() => {}`, `(x: number) => string`)
397
- * @template T - The type to evaluate.
398
- * @example
399
- * ```ts
400
- * // Special keywords
401
- * type A = IsBaseType<any>; // ➔ true
402
- * type B = IsBaseType<unknown>; // ➔ true
403
- * type C = IsBaseType<never>; // ➔ true
404
- *
405
- * // Primitives
406
- * type PS1 = IsBaseType<string>; // ➔ true
407
- * type PS2 = IsBaseType<"hi">; // ➔ false
408
- * type PN1 = IsBaseType<number>; // ➔ true
409
- * type PN2 = IsBaseType<42>; // ➔ false
410
- * type PB1 = IsBaseType<boolean>; // ➔ true
411
- * type PB2 = IsBaseType<true>; // ➔ false
412
- * type PB3 = IsBaseType<false>; // ➔ false
413
- * type PBi1 = IsBaseType<bigint>; // ➔ true
414
- * type PBi2 = IsBaseType<123n>; // ➔ false
415
- *
416
- * // Functions
417
- * type H = IsBaseType<Function>; // ➔ true
418
- * type I = IsBaseType<AnyFunction>; // ➔ true
419
- * type J = IsBaseType<() => {}>; // ➔ false
420
- *
421
- * // Arrays
422
- * type K = IsBaseType<[]>; // ➔ false
423
- * type L = IsBaseType<string[]>; // ➔ true
424
- * type M = IsBaseType<(string | number)[]>; // ➔ true
425
- *
426
- * // Built-ins
427
- * type N = IsBaseType<Date>; // ➔ true
428
- * type O = IsBaseType<new Date()>; // ➔ false
429
- * type P = IsBaseType<Promise<any>>; // ➔ true
430
- * type Q = IsBaseType<Promise<42>>; // ➔ false
431
- *
432
- * // Objects
433
- * type R = IsBaseType<object>; // ➔ true
434
- * type S = IsBaseType<{ a: 1 }>; // ➔ false
435
- * type T = IsBaseType<{}>; // ➔ true
436
- * ```
437
- */
438
- type IsBaseType<T>=IsAny<T>extends true?true:IsUnknown<T>extends true?true:IsNever<T>extends true?true:IsExactly<T,null>extends true?true:IsExactly<T,undefined>extends true?true:IsExactly<T,void>extends true?true:IsExactly<T,string>extends true?true:IsExactly<T,number>extends true?true:IsExactly<T,boolean>extends true?true:IsExactly<T,bigint>extends true?true:IsExactly<T,symbol>extends true?true:IsExactly<T,Function>extends true?true:IsExactly<T,AnyFunction>extends true?true:IsGeneralArray<T>extends true?true:IsExactly<T,TypedArray>extends true?true:IsExactly<T,Date>extends true?true:IsExactly<T,RegExp>extends true?true:IsExactly<T,Error>extends true?true:T extends Promise<infer U>?IsBaseType<U>extends true?true:false:T extends Map<infer K,infer V>?IsBaseType<K>extends true?IsBaseType<V>extends true?true:false:false:T extends WeakMap<infer K,infer V>?K extends object?IsBaseType<V>extends true?true:false:false:T extends Set<infer U>?IsBaseType<U>extends true?true:false:T extends WeakSet<infer U>?U extends object?true:false:IsExactly<T,ArrayBuffer>extends true?true:IsExactly<T,SharedArrayBuffer>extends true?true:IsExactly<T,DataView>extends true?true:IsExactly<T,{}>extends true?true:[ T] extends [object]?[object] extends [T]?true:false:false;
439
- /**
440
- * Helper for {@link ReplaceAll}
441
- */
442
- type Includes$1<S extends string,Sub extends string>=S extends`${infer _}${Sub}${infer _}`?true:false;
443
- /** -------------------------------------------------------
444
- * * ***Utility Type: `ReplaceAll`.***
445
- * -------------------------------------------------------
446
- * **A **type-level utility** that replaces all occurrences of a given string (or array of strings) `Pivot` in a string `T` with `ReplaceBy`.**
447
- * - **Supports:**
448
- * - Replacing a single substring.
449
- * - Replacing multiple substrings (Pivot as array).
450
- * - Guards against infinite recursion if `ReplaceBy` contains any value in Pivot.
451
- * @template T - The string to process.
452
- * @template Pivot - A string or readonly array of strings to replace.
453
- * @template ReplaceBy - The string to replace Pivot with.
454
- * @example
455
- * ```ts
456
- * // Single pivot string
457
- * type Case1 = ReplaceAll<'remove me me', 'me', 'him'>;
458
- * // ➔ 'remove him him'
459
- *
460
- * // Pivot as array
461
- * type Case2 = ReplaceAll<'remove me remove me', ['me', 'remove'], 'him'>;
462
- * // ➔ 'him him him him'
463
- *
464
- * // Pivot not found
465
- * type Case3 = ReplaceAll<'hello world', 'foo', 'bar'>;
466
- * // ➔ 'hello world'
467
- *
468
- * // ReplaceBy contains pivot (guard against infinite recursion)
469
- * type Case4 = ReplaceAll<'abc', 'a', 'a'>;
470
- * // ➔ string
471
- * ```
472
- * @remarks
473
- * - Works recursively to replace all instances.
474
- * - If Pivot is empty (`""`) or empty array (`[]`), returns `T` unchanged.
475
- */
476
- type ReplaceAll<T extends string,Pivot extends string|readonly string[],ReplaceBy extends string>=Pivot extends""|[]?T:Includes$1<ReplaceBy,Pivot extends string?Pivot:never>extends true?string:Pivot extends readonly [infer First extends string,...infer Rest extends string[]]?ReplaceAll<ReplaceAll<T,First,ReplaceBy>,Rest,ReplaceBy>:Pivot extends string?T extends`${infer A}${Pivot}${infer B}`?ReplaceAll<`${A}${ReplaceBy}${B}`,Pivot,ReplaceBy>:T:T;
477
- /** -------------------------------------------------------
478
- * * ***Utility Type: `IsTuple`.***
479
- * -------------------------------------------------------
480
- * **Returns a boolean whether the first array argument is fixed length tuple.**
481
- * @template T - The array to check.
482
- * @example
483
- * type Case1 = IsTuple<[1, 2, 3]>; // ➔ true
484
- * type Case2 = IsTuple<number[]>; // ➔ false
485
- */
486
- type IsTuple<T extends readonly unknown[]>=NotExtends<number,T["length"]>;
487
- /** -------------------------------------------------------
488
- * * ***Utility Type: `IfTuple`.***
489
- * -------------------------------------------------------
490
- * **Returns the second argument if the first array argument is fixed length
491
- * tuple (defaults to `true`), otherwise returns the third argument (defaults
492
- * to `false`).**
493
- * @template T - The array to check.
494
- * @template IfTrue - The branch type if condition is met. (default: `true`).
495
- * @template IfFalse - The branch type if condition is not met. (default: `false`).
496
- * @example
497
- * type Case1 = IfTuple<[1, 2, 3], 'valid'>;
498
- * // ➔ 'valid'
499
- * type Case2 = IfTuple<number[], 'valid', 'invalid'>;
500
- * // ➔ 'invalid'
501
- */
502
- type IfTuple<T extends readonly unknown[],IfTrue=true,IfFalse=false>=If<IsTuple<T>,IfTrue,IfFalse>;
503
- /** -------------------------------------------------------
504
- * * ***Utility Type: `RemoveLeading`.***
505
- * -------------------------------------------------------
506
- * **Accepts a string type `T` and **recursively removes leading characters**
507
- * specified in `Characters`.**
508
- * @template T - The string to process.
509
- * @template Characters - The characters to remove from the start.
510
- * @example
511
- * ```ts
512
- * type Case1 = RemoveLeading<'aaabc', 'a'>;
513
- * // ➔ 'bc' (all leading 'a' removed).
514
- * type Case2 = RemoveLeading<'abc', 'd'>;
515
- * // ➔ 'abc' (no 'd' at start, unchanged).
516
- * type Case3 = RemoveLeading<'aaa', 'a'>;
517
- * // ➔ '' (all 'a' removed).
518
- * type Case4 = RemoveLeading<'aaa', 'aa'>;
519
- * // ➔ 'a' (matches 'aa' once, then remaining 'a').
520
- * ```
521
- */
522
- type RemoveLeading<T extends string,Characters extends string>=T extends`${Characters}${infer Rest extends string}`?IsEmptyString<Rest>extends true?Rest:RemoveLeading<Rest,Characters>:T;type SubDecrementMap={"-9":-10;"-8":-9;"-7":-8;"-6":-7;"-5":-6;"-4":-5;"-3":-4;"-2":-3;"-1":-2;"0":-1;"1":0;"2":1;"3":2;"4":3;"5":4;"6":5;"7":6;"8":7;"9":8;};type SubNegativeCarryMap={"-10":0;"-9":1;"-8":2;"-7":3;"-6":4;"-5":5;"-4":6;"-3":7;"-2":8;"-1":9;};type SubMap={0:[0,-1,-2,-3,-4,-5,-6,-7,-8,-9];1:[1,0,-1,-2,-3,-4,-5,-6,-7,-8];2:[2,1,0,-1,-2,-3,-4,-5,-6,-7];3:[3,2,1,0,-1,-2,-3,-4,-5,-6];4:[4,3,2,1,0,-1,-2,-3,-4,-5];5:[5,4,3,2,1,0,-1,-2,-3,-4];6:[6,5,4,3,2,1,0,-1,-2,-3];7:[7,6,5,4,3,2,1,0,-1,-2];8:[8,7,6,5,4,3,2,1,0,-1];9:[9,8,7,6,5,4,3,2,1,0];};type _RemoveLeadingZeros<T extends string>=ParseNumber<RemoveLeading<T,"0">extends infer WithoutLeadingZeros extends string?IfEmptyString<WithoutLeadingZeros,"0",WithoutLeadingZeros>:never>;type _Sub<Num1 extends string,Num2 extends string,NegativeCarry extends 0|1=0,Result extends string="">=IsEmptyString<Num2>extends true?NegativeCarry extends 0?`${Num1}${Result}`:`${Decrement<ParseNumber<Num1>>}${Result}`:LastCharacter<Num1>extends`${infer Num1LastDigit extends keyof SubMap & number}`?LastCharacter<Num2>extends`${infer Num2LastDigit extends keyof SubMap[Num1LastDigit] & number}`?`${SubMap[Num1LastDigit][Num2LastDigit]}`extends infer DigitsSub extends keyof SubDecrementMap?(NegativeCarry extends 1?Stringify<SubDecrementMap[DigitsSub]>:DigitsSub)extends infer DigitsSubWithCarry extends string?Num1 extends`${infer Num1Rest}${Num1LastDigit}`?Num2 extends`${infer Num2Rest}${Num2LastDigit}`?DigitsSubWithCarry extends keyof SubNegativeCarryMap?_Sub<Num1Rest,Num2Rest,1,`${SubNegativeCarryMap[DigitsSubWithCarry]}${Result}`>:_Sub<Num1Rest,Num2Rest,0,`${DigitsSubWithCarry}${Result}`>:never:never:never:never:never:never;
523
- /** -------------------------------------------------------
524
- * * ***Utility Type: `Sub`.***
525
- * -------------------------------------------------------
526
- * **Computes the subtraction of two integers at the **type level**.**
527
- * - **Behavior:**
528
- * - Handles positive and negative numbers.
529
- * - Supports numbers in the range `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
530
- * - Internally performs string-based arithmetic to handle carries/borrows.
531
- * @template Num1 - First number (minuend).
532
- * @template Num2 - Second number (subtrahend).
533
- * @example
534
- * ```ts
535
- * // Positive numbers
536
- * type Case1 = Sub<10, 2>; // ➔ 8
537
- *
538
- * // Num1 smaller than Num2
539
- * type Case2 = Sub<2, 10>; // ➔ -8
540
- *
541
- * // Subtract negative number
542
- * type Case3 = Sub<2, -10>; // ➔ 12
543
- *
544
- * // Subtract from negative number
545
- * type Case4 = Sub<-2, 10>; // ➔ -12
546
- *
547
- * // Both negative
548
- * type Case5 = Sub<-5, -2>; // ➔ -3
549
- * type Case6 = Sub<-2, -5>; // ➔ 3
550
- * ```
551
- */
552
- type Sub<Num1 extends number,Num2 extends number>=IsNegativeInteger<Num1>extends true?IsNegativeInteger<Num2>extends true?IsLowerThan<Num1,Num2>extends true?Negate<_RemoveLeadingZeros<_Sub<Stringify<Abs<Num1>>,Stringify<Abs<Num2>>>>>:_RemoveLeadingZeros<_Sub<Stringify<Abs<Num2>>,Stringify<Abs<Num1>>>>:Sum<Abs<Num1>,Num2>extends infer Result extends number?Negate<Result>:never:IsNegativeInteger<Num2>extends true?Sum<Num1,Abs<Num2>>:IsLowerThan<Num1,Num2>extends true?Negate<_RemoveLeadingZeros<_Sub<Stringify<Num2>,Stringify<Num1>>>>:_RemoveLeadingZeros<_Sub<Stringify<Num1>,Stringify<Num2>>>;type SumIncrementMap=[ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];type SumLastDigitMap={10:0;11:1;12:2;13:3;14:4;15:5;16:6;17:7;18:8;19:9;};type SumMap={0:[0,1,2,3,4,5,6,7,8,9];1:[1,2,3,4,5,6,7,8,9,10];2:[2,3,4,5,6,7,8,9,10,11];3:[3,4,5,6,7,8,9,10,11,12];4:[4,5,6,7,8,9,10,11,12,13];5:[5,6,7,8,9,10,11,12,13,14];6:[6,7,8,9,10,11,12,13,14,15];7:[7,8,9,10,11,12,13,14,15,16];8:[8,9,10,11,12,13,14,15,16,17];9:[9,10,11,12,13,14,15,16,17,18];};
553
- /** -------------------------------------------------------
554
- * * ***Private Utility Type: `_Sum`.***
555
- * -------------------------------------------------------
556
- * **Internal helper type for summing two integer numbers represented as strings.**
557
- * - Performs digit-by-digit addition with carry handling.
558
- * @deprecated This is internal helper, use {@link Sum | **`Sum`**} instead.
559
- * @template Num1 - First number as string.
560
- * @template Num2 - Second number as string.
561
- * @template Carry - Carry flag (0 or 1), defaults to 0.
562
- * @template Result - Accumulated result string, defaults to empty string.
563
- */
564
- type _Sum<Num1 extends string,Num2 extends string,Carry extends 0|1=0,Result extends string="">=IsEmptyString<Num1>extends true?Carry extends 0?ParseNumber<`${Num2}${Result}`>:_Increment<Num2,Result>:IsEmptyString<Num2>extends true?Carry extends 0?ParseNumber<`${Num1}${Result}`>:_Increment<Num1,Result>:LastCharacter<Num1>extends`${infer Num1LastDigit extends keyof SumMap & number}`?LastCharacter<Num2>extends`${infer Num2LastDigit extends keyof SumMap[Num1LastDigit] & number}`?SumMap[Num1LastDigit][Num2LastDigit] extends infer DigitsSum extends number?(Carry extends 1?SumIncrementMap[DigitsSum]:DigitsSum)extends infer DigitsSumWithCarry extends number?Num1 extends`${infer Num1Rest}${Num1LastDigit}`?Num2 extends`${infer Num2Rest}${Num2LastDigit}`?DigitsSumWithCarry extends keyof SumLastDigitMap?_Sum<Num1Rest,Num2Rest,1,`${SumLastDigitMap[DigitsSumWithCarry]}${Result}`>:_Sum<Num1Rest,Num2Rest,0,`${DigitsSumWithCarry}${Result}`>:never:never:never:never:never:never;
565
- /** -------------------------------------------------------
566
- * * ***Utility Type: `Sum`.***
567
- * -------------------------------------------------------
568
- * **Adds two integers at the type level. Handles positive and negative numbers.**
569
- * - Supports numbers in the range:
570
- * - `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
571
- * @template Num1 - First number.
572
- * @template Num2 - Second number.
573
- * @example
574
- * ```ts
575
- * // Positive + positive
576
- * type Case1 = Sum<4, 9>; // ➔ 13
577
- *
578
- * // Negative + positive
579
- * type Case2 = Sum<-4, 9>; // ➔ 5
580
- *
581
- * // Positive + negative
582
- * type Case3 = Sum<4, -9>; // ➔ -5
583
- *
584
- * // Negative + negative
585
- * type Case4 = Sum<-4, -9>; // ➔ -13
586
- * ```
587
- */
588
- type Sum<Num1 extends number,Num2 extends number>=IsNegativeInteger<Num1>extends true?IsNegativeInteger<Num2>extends true?Negate<_Sum<Stringify<Abs<Num1>>,Stringify<Abs<Num2>>>>:Sub<Num2,Abs<Num1>>:IsNegativeInteger<Num2>extends true?Sub<Num1,Abs<Num2>>:_Sum<Stringify<Num1>,Stringify<Num2>>;type _safeSumArr<Rest extends number[],CurrentSum extends number,Num1 extends number>=
589
- /** @ts-expect-error this still safe not to much deep */
590
- _SumArr<Rest,Sum<CurrentSum,Num1>>;type _SumArr<T extends readonly number[],CurrentSum extends number=0>=IsEmptyArray<T>extends true?CurrentSum:Pop<T,{includeRemoved:true;}>extends infer PopResult?IsNever<PopResult>extends true?CurrentSum:PopResult extends [infer Rest extends number[],infer Num1 extends number]?_safeSumArr<Rest,CurrentSum,Num1>:never:CurrentSum;
591
- /** -------------------------------------------------------
592
- * * ***Utility Type: `SumArr`.***
593
- * -------------------------------------------------------
594
- * **Accepts a tuple of numbers and returns their sum.**
595
- * - **Behavior:**
596
- * - Only works on tuple types (not general arrays).
597
- * - Supports numbers in the range:
598
- * -`[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
599
- * @template T - Tuple of numbers to sum.
600
- * @example
601
- * ```ts
602
- * // Sum all elements in a tuple
603
- * type Case1 = SumArr<[1, 2, 3, 4]>; // ➔ 10
604
- *
605
- * // Tuple with negative number
606
- * type Case2 = SumArr<[1, 2, 3, -4]>; // ➔ 2
607
- * ```
608
- */
609
- type SumArr<T extends readonly number[]>=IsTuple<T>extends true?_SumArr<T>:never;
610
- /** @ts-expect-error this still safe not to much deep */
611
- type _safeSum<Parts extends [string[],string[],string[],string[]]=[[],[],[],[]]>=Sum<Sum<Parts[0]["length"],Parts[1]["length"]>,Sum<Parts[2]["length"],Parts[3]["length"]>>;type _StringLength<S extends string,Parts extends [string[],string[],string[],string[]]=[[],[],[],[]]>=S extends""?_safeSum<Parts>:S extends`${infer C1 extends string}${infer Rest1 extends string}`?Rest1 extends`${infer C2 extends string}${infer Rest2 extends string}`?Rest2 extends`${infer C3 extends string}${infer Rest3 extends string}`?Rest3 extends`${infer C4 extends string}${infer Rest4 extends string}`?_StringLength<Rest4,[ [...Parts[0],C1],[...Parts[1],C2],[...Parts[2],C3],[...Parts[3],C4]]>:_StringLength<Rest3,[ [...Parts[0],C1],[...Parts[1],C2],[...Parts[2],C3],Parts[3]]>:_StringLength<Rest2,[[...Parts[0],C1],[...Parts[1],C2],Parts[2],Parts[3]]>:_StringLength<Rest1,[[...Parts[0],C1],Parts[1],Parts[2],Parts[3]]>:_StringLength<S,Parts>;
612
- /** -------------------------------------------------------
613
- * * ***Utility Type: `StringLength`.***
614
- * -------------------------------------------------------
615
- * **Returns the length of a string at the type level.**
616
- * - Supports string length in range `[0, 3968]`.
617
- * @template S - The string to measure.
618
- * @example
619
- * ```ts
620
- * type Case1 = StringLength<''>;
621
- * // ➔ 0
622
- * type Case2 = StringLength<'xxx'>;
623
- * // ➔ 3
624
- * ```
625
- */
626
- type StringLength<S extends string>=_StringLength<S>;
627
- /** -------------------------------------------------------
628
- * * ***Utility Type: `CompareStringLength`.***
629
- * -------------------------------------------------------
630
- * - **Compares the lengths of two strings and returns one of three possible type values:**
631
- * - `IfStr1Shorter` if the first string is shorter.
632
- * - `IfStr2Shorter` if the second string is shorter.
633
- * - `IfEqual` if both strings have the same length.
634
- * - Defaults to `never` if not provided.
635
- * @template Str1 - First string.
636
- * @template Str2 - Second string.
637
- * @template IfStr1Shorter - Type to return if Str1 is shorter (default `never`).
638
- * @template IfStr2Shorter - Type to return if Str2 is shorter (default `never`).
639
- * @template IfEqual - Type to return if both strings have equal length (default `never`).
640
- * @example
641
- * ```ts
642
- * type Case1 = CompareStringLength<'a', 'ab', 'first shorter'>;
643
- * // ➔ 'first shorter'
644
- * type Case2 = CompareStringLength<'abc', 'ab', 'first shorter', 'first longer'>;
645
- * // ➔ 'first longer'
646
- * type Case3 = CompareStringLength<'ab', 'ab', 'first shorter', 'first longer', 'equal'>;
647
- * // ➔ 'equal'
648
- * ```
649
- */
650
- type CompareStringLength<Str1 extends string,Str2 extends string,IfStr1Shorter=never,IfStr2Shorter=never,IfEqual=never>=IsEmptyString<Str1>extends true?IsEmptyString<Str2>extends true?IfEqual:IfStr1Shorter:IsEmptyString<Str2>extends true?IfStr2Shorter:Str1 extends`${string}${infer Str1Rest extends string}`?Str2 extends`${string}${infer Str2Rest extends string}`?CompareStringLength<Str1Rest,Str2Rest,IfStr1Shorter,IfStr2Shorter,IfEqual>:never:never;
651
- /** -------------------------------------------------------
652
- * * ***Utility Type: `IsShorterString`.***
653
- * -------------------------------------------------------
654
- * **Returns `true` if the first string is shorter than the second string; otherwise `false`.**
655
- * @template Str1 - First string.
656
- * @template Str2 - Second string.
657
- * @example
658
- * ```ts
659
- * type Case1 = IsShorterString<'a', 'ab'>;
660
- * // ➔ true
661
- * type Case2 = IsShorterString<'abc', 'ab'>;
662
- * // ➔ false
663
- * ```
664
- */
665
- type IsShorterString<Str1 extends string,Str2 extends string>=CompareStringLength<Str1,Str2,true,false,false>;
666
- /** -------------------------------------------------------
667
- * * ***Utility Type: `IsLongerString`.***
668
- * -------------------------------------------------------
669
- * **Returns `true` if the first string is longer than the second string; otherwise `false`.**
670
- * @template Str1 - First string.
671
- * @template Str2 - Second string.
672
- * @example
673
- * ```ts
674
- * type Case1 = IsLongerString<'ab', 'a'>; // ➔ true
675
- * type Case2 = IsLongerString<'a', 'ab'>; // ➔ false
676
- * ```
677
- */
678
- type IsLongerString<Str1 extends string,Str2 extends string>=CompareStringLength<Str1,Str2,false,true,false>;
679
- /** -------------------------------------------------------
680
- * * ***Utility Type: `IsSameLengthString`.***
681
- * -------------------------------------------------------
682
- * **Returns `true` if two strings have the same length; otherwise `false`.**
683
- * @template Str1 - First string.
684
- * @template Str2 - Second string.
685
- * @example
686
- * ```ts
687
- * type Case1 = IsSameLengthString<'ab', 'ab'>; // ➔ true
688
- * type Case2 = IsSameLengthString<'ab', 'abc'>; // ➔ false
689
- * ```
690
- */
691
- type IsSameLengthString<Str1 extends string,Str2 extends string>=CompareStringLength<Str1,Str2,false,false,true>;
692
- /** -------------------------------------------------------
693
- * * ***Type Options for {@link NumberLength | **`NumberLength`**}.***
694
- */
695
- type TypeNumberLengthOptions={
696
- /** * ***Removes the leading minus `-` from negative numbers, default: `true`.***
697
- *
698
- * @default true
699
- */
700
- stripSign?:boolean;
701
- /** * ***Removes the decimal point `.` from floats, default: `true`.***
702
- *
703
- * @default true
704
- */
705
- stripDot?:boolean;
706
- /** * ***Removes the trailing `n` from BigInt literals, default: `true`.***
707
- *
708
- * @default true
709
- */
710
- stripBigInt?:boolean;};
711
- /** -------------------------------------------------------
712
- * * ***Default options for {@link NumberLength | **`NumberLength`**} (all `true`).***
713
- */
714
- type DefaultNumberLengthOptions={stripSign:true;stripDot:true;stripBigInt:true;};
715
- /** -------------------------------------------------------
716
- * * ***Merge provided options with defaults for {@link NumberLength | **`NumberLength`**}.***
717
- */
718
- type MergeOptions<Opts extends TypeNumberLengthOptions>={[K in keyof DefaultNumberLengthOptions]:K extends keyof Opts?Opts[K]:DefaultNumberLengthOptions[K];};
719
- /** -------------------------------------------------------
720
- * * ***Utility Type: `NumberLength`.***
721
- * -------------------------------------------------------
722
- * **A type-level utility that returns the **number of digits/characters**
723
- * of a numeric literal type, with optional cleaning.**
724
- * - **Supports:**
725
- * - Integers (positive & negative).
726
- * - Floats (`.` optionally removed).
727
- * - Scientific notation (`e`/`E`, TypeScript normalizes to number).
728
- * - BigInts (`n` suffix optionally removed).
729
- * @template T - A numeric literal (`number` or `bigint`).
730
- * @template Options - Optional configuration (default: all `true`):
731
- * - `stripSign` ➔ Removes the leading `-` (default `true`).
732
- * - `stripDot` ➔ Removes the decimal point `.` (default `true`).
733
- * - `stripBigInt` ➔ Removes trailing `n` (default `true`).
734
- * @example
735
- * #### ✅ _Valid Examples:_
736
- * ```ts
737
- * // Integers
738
- * type A = NumberLength<100>; // ➔ 3
739
- * type B = NumberLength<-100>; // ➔ 3 (minus stripped by default)
740
- * type C = NumberLength<-100, { stripSign: false }>; // ➔ 4 (minus kept)
741
- *
742
- * // Floats
743
- * type D = NumberLength<0.25>; // ➔ 2 (dot removed)
744
- * type E = NumberLength<-0.25>; // ➔ 2 (minus & dot removed)
745
- * type F = NumberLength<12.34, { stripDot: false }>; // ➔ 5 (12.34)
746
- *
747
- * // Scientific notation
748
- * type G = NumberLength<5e4>; // ➔ 5 (50000)
749
- * type H = NumberLength<-5e4>; // ➔ 5 (-50000, minus stripped)
750
- * type I = NumberLength<-5e4,{ stripSign:false }>; // ➔ 6 (-50000, minus not stripped)
751
- *
752
- * // BigInts
753
- * type J = NumberLength<12n>; // ➔ 2
754
- * type K = NumberLength<-2125n>; // ➔ 4 (- & n removed)
755
- * type L = NumberLength<-2125n, { stripSign: false }>;
756
- * // ➔ 5 (minus kept)
757
- * type M = NumberLength<123n, { stripBigInt: false }>;
758
- * // ➔ 4 (123n)
759
- * type N = NumberLength<-123n, { stripBigInt: false, stripSign: false }>;
760
- * // ➔ 5 (minus & n kept ➔ -123n)
761
- * ```
762
- * ---
763
- * #### ❌ _Invalid Examples:_
764
- * ```ts
765
- * type Invalid1 = NumberLength<string>; // ➔ never
766
- * type Invalid2 = NumberLength<boolean>; // ➔ never
767
- * type Invalid3 = NumberLength<"123">; // ➔ never (string literal)
768
- * type Invalid4 = NumberLength<number>; // ➔ never (not literal)
769
- * type Invalid5 = NumberLength<bigint>; // ➔ never (not literal)
770
- * type Invalid6 = NumberLength<any>; // ➔ never
771
- * type Invalid7 = NumberLength<unknown>; // ➔ never
772
- * type Invalid8 = NumberLength<never>; // ➔ never
773
- * ```
774
- * ---
775
- * @remarks
776
- * - Uses type-level string manipulation to "clean" numeric literal according to options.
777
- * - Removes `-`, `.`, or `n` if corresponding option is true.
778
- * - Works reliably for literal numbers, floats, and BigInt.
779
- * - Scientific notation is normalized by TypeScript, so `5e4` becomes `50000`.
780
- */
781
- type NumberLength<T extends number|bigint,Options extends Partial<TypeNumberLengthOptions>=DefaultNumberLengthOptions>=If<OrArr<[IsBaseType<T>,Extends<T,string>,Not<Extends<T,number|bigint>>]>>extends true?never:StringLength<ReplaceAll<Stringify<T>,[ MergeOptions<Options>["stripSign"] extends true?"-":"",MergeOptions<Options>["stripDot"] extends true?".":"",MergeOptions<Options>["stripBigInt"] extends true?"n":""],"">>;
782
- /** -------------------------------------------------------
783
- * * ***Utility Type: `CompareNumberLength`.***
784
- * -------------------------------------------------------
785
- * **Compares the **number of digits** of two numeric literal types.**
786
- * - **Returns:**
787
- * - `IfNum1Shorter` if the first number has fewer digits than the second (default: `never`).
788
- * - `IfNum2Shorter` if the second number has fewer digits than the first (default: `never`).
789
- * - `IfEqual` if both numbers have the same number of digits (default: `never`).
790
- * - **Important:**
791
- * - This utility only works with **literal numbers**.
792
- * - Using non-literal numbers (`number`) will return `never`.
793
- * @template Num1 - The first number literal to compare.
794
- * @template Num2 - The second number literal to compare.
795
- * @template IfNum1Shorter - Return type if the first number is shorter (default: `never`).
796
- * @template IfNum2Shorter - Return type if the second number is shorter (default: `never`).
797
- * @template IfEqual - Return type if both numbers have the same length (default: `never`).
798
- * @example
799
- * ```ts
800
- * // First number shorter than second
801
- * type Case1 = CompareNumberLength<1, 12, 'first shorter'>;
802
- * // ➔ 'first shorter'
803
- *
804
- * // First number longer than second
805
- * type Case2 = CompareNumberLength<123, 12, 'first shorter', 'first longer'>;
806
- * // ➔ 'first longer'
807
- *
808
- * // Both numbers have equal length
809
- * type Case3 = CompareNumberLength<12, 12, 'first shorter', 'first longer', 'equal'>;
810
- * // ➔ 'equal'
811
- *
812
- * // Defaults (no custom return types)
813
- * type Case4 = CompareNumberLength<1, 12>;
814
- * // ➔ never
815
- *
816
- * // Non-literal numbers
817
- * type NumA = number;
818
- * type NumB = 12;
819
- * type Case4 = CompareNumberLength<NumA, NumB, 'first shorter', 'first longer', 'equal'>;
820
- * // ➔ never
821
- * ```
822
- * ---
823
- * @remarks
824
- * - Internally uses {@link Stringify | **`Stringify`**} and {@link CompareStringLength | **`CompareStringLength`**}.
825
- * - Works for `positive`, `negative`, and `floating-point literal numbers`.
826
- */
827
- type CompareNumberLength<Num1 extends number,Num2 extends number,IfNum1Shorter=never,IfNum2Shorter=never,IfEqual=never>=If<Or<Extends<number,Num1>,Extends<number,Num2>>>extends true?never:CompareStringLength<Stringify<Num1>,Stringify<Num2>,IfNum1Shorter,IfNum2Shorter,IfEqual>;
828
- /** -------------------------------------------------------
829
- * * ***Utility Type: `IsShorterNumber`.***
830
- * -------------------------------------------------------
831
- * **Compares the number of digits of two numeric literal types and returns a **boolean**.**
832
- * - **Returns:**
833
- * - `true` if the first number has fewer digits than the second.
834
- * - `false` otherwise (including when numbers have equal length).
835
- * - **Important:**
836
- * - This utility only works with **literal numbers**.
837
- * - Using non-literal numbers (`number`) will return `never`.
838
- * @template Num1 - The first number literal to compare.
839
- * @template Num2 - The second number literal to compare.
840
- * @example
841
- * ```ts
842
- * // Literal numbers
843
- * type Case1 = IsShorterNumber<1, 10>;
844
- * // ➔ true
845
- *
846
- * type Case2 = IsShorterNumber<100, 10>;
847
- * // ➔ false
848
- *
849
- * type Case3 = IsShorterNumber<12, 12>;
850
- * // ➔ false
851
- *
852
- * // Non-literal numbers
853
- * type NumA = number;
854
- * type NumB = 12;
855
- * type Case4 = IsShorterNumber<NumA, NumB>;
856
- * // ➔ never
857
- * ```
858
- * ---
859
- * @remarks
860
- * - Internally uses {@link CompareNumberLength | **`CompareNumberLength`**}.
861
- * - Works for `positive`, `negative`, and `floating-point literal numbers`.
862
- */
863
- type IsShorterNumber<Num1 extends number,Num2 extends number>=CompareNumberLength<Num1,Num2,true,false,false>;
864
- /** -------------------------------------------------------
865
- * * ***Utility Type: `IsLongerNumber`.***
866
- * -------------------------------------------------------
867
- * **Compares the number of digits of two numeric literal types and returns a **boolean**.**
868
- * - **Returns:**
869
- * - `true` if the first number has more digits than the second.
870
- * - `false` otherwise (including when numbers have equal length).
871
- * - **Important:**
872
- * - Only works with **literal numbers**.
873
- * - Non-literal numbers (`number`) return `never`.
874
- * @template Num1 - The first number literal to compare.
875
- * @template Num2 - The second number literal to compare.
876
- * @example
877
- * ```ts
878
- * type Case1 = IsLongerNumber<10, 1>;
879
- * // ➔ true
880
- *
881
- * type Case2 = IsLongerNumber<10, 100>;
882
- * // ➔ false
883
- *
884
- * type Case3 = IsLongerNumber<12, 12>;
885
- * // ➔ false
886
- *
887
- * // Non-literal numbers
888
- * type NumA = number;
889
- * type NumB = 12;
890
- * type Case4 = IsLongerNumber<NumA, NumB>;
891
- * // ➔ never
892
- * ```
893
- * ---
894
- * @remarks
895
- * - Internally uses {@link CompareNumberLength | **`CompareNumberLength`**}.
896
- * - Works for `positive`, `negative`, and `floating-point literal numbers`.
897
- */
898
- type IsLongerNumber<Num1 extends number,Num2 extends number>=CompareNumberLength<Num1,Num2,false,true,false>;
899
- /** -------------------------------------------------------
900
- * * ***Utility Type: `IsSameLengthNumber`.***
901
- * -------------------------------------------------------
902
- * **Compares the number of digits of two numeric literal types and returns a **boolean**.**
903
- * - **Returns:**
904
- * - `true` if the numbers have the same number of digits.
905
- * - `false` otherwise.
906
- * - **Important:**
907
- * - Only works with **literal numbers**.
908
- * - Non-literal numbers (`number`) return `never`.
909
- * @template Num1 - The first number literal to compare.
910
- * @template Num2 - The second number literal to compare.
911
- * @example
912
- * ```ts
913
- * type Case1 = IsSameLengthNumber<10, 10>;
914
- * // ➔ true
915
- *
916
- * type Case2 = IsSameLengthNumber<10, 100>;
917
- * // ➔ false
918
- *
919
- * // Non-literal numbers
920
- * type NumA = number;
921
- * type NumB = 12;
922
- * type Case3 = IsSameLengthNumber<NumA, NumB>;
923
- * // ➔ never
924
- * ```
925
- * ---
926
- * @remarks
927
- * - Internally uses {@link CompareNumberLength | **`CompareNumberLength`**}.
928
- * - Works for `positive`, `negative`, and `floating-point literal numbers`.
929
- */
930
- type IsSameLengthNumber<Num1 extends number,Num2 extends number>=CompareNumberLength<Num1,Num2,false,false,true>;type LowerThanMap={"0":["1","2","3","4","5","6","7","8","9"];"1":["2","3","4","5","6","7","8","9"];"2":["3","4","5","6","7","8","9"];"3":["4","5","6","7","8","9"];"4":["5","6","7","8","9"];"5":["6","7","8","9"];"6":["7","8","9"];"7":["8","9"];"8":["9"];"9":[];};type _IsLowerThan<Num1 extends string,Num2 extends string>=Num1 extends`${infer Num1Character extends keyof LowerThanMap}${infer Num1Rest extends string}`?Num2 extends`${infer Num2Character extends string}${infer Num2Rest extends string}`?IsEqual<Num1Character,Num2Character>extends true?_IsLowerThan<Num1Rest,Num2Rest>:Num2Character extends LowerThanMap[Num1Character][number]?true:false:true:false;
931
- /** -------------------------------------------------------
932
- * * ***Utility Type: `IsLowerThan`.***
933
- * -------------------------------------------------------
934
- * **Returns a boolean indicating whether `Num1` is strictly lower than `Num2`.**
935
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
936
- * @template Num1 - The first integer to compare.
937
- * @template Num2 - The second integer to compare.
938
- * @example
939
- * type Case1 = IsLowerThan<1, 10>; // ➔ true
940
- * type Case2 = IsLowerThan<1, -10>; // ➔ false
941
- */
942
- type IsLowerThan<Num1 extends number,Num2 extends number>=IsEqual<Num1,Num2>extends true?false:IsNegative<Num1>extends true?IsNegative<Num2>extends false?true:CompareNumberLength<Num1,Num2,false,true,Not<_IsLowerThan<Stringify<Abs<Num1>>,Stringify<Abs<Num2>>>>>:IsNegative<Num2>extends true?false:CompareNumberLength<Num1,Num2,true,false,_IsLowerThan<Stringify<Abs<Num1>>,Stringify<Abs<Num2>>>>;
943
- /** -------------------------------------------------------
944
- * * ***Utility Type: `IfLowerThan`.***
945
- * -------------------------------------------------------
946
- * **Returns `IfTrue` if `Num1` is lower than `Num2`, otherwise returns `IfFalse`.**
947
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
948
- * @template Num1 - The first integer to compare.
949
- * @template Num2 - The second integer to compare.
950
- * @template IfTrue - Value to return if `Num1 < Num2`.
951
- * @template IfFalse - Value to return if `Num1 >= Num2`.
952
- * @example
953
- * type Case1 = IfLowerThan<1, 10, 'valid'>;
954
- * // ➔ 'valid'
955
- * type Case2 = IfLowerThan<1, -10, 'valid', 'invalid'>;
956
- * // ➔ 'invalid'
957
- */
958
- type IfLowerThan<Num1 extends number,Num2 extends number,IfTrue=true,IfFalse=false>=If<IsLowerThan<Num1,Num2>,IfTrue,IfFalse>;
959
- /** -------------------------------------------------------
960
- * * ***Utility Type: `IsLowerOrEqual`.***
961
- * -------------------------------------------------------
962
- * **Returns a boolean indicating whether `Num1` is lower than or equal to `Num2`.**
963
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
964
- * @template Num1 - The first integer to compare.
965
- * @template Num2 - The second integer to compare.
966
- * @example
967
- * type Case1 = IsLowerOrEqual<1, 10>;
968
- * // ➔ true
969
- * type Case2 = IsLowerOrEqual<1, -10>;
970
- * // ➔ false
971
- */
972
- type IsLowerOrEqual<Num1 extends number,Num2 extends number>=IsEqual<Num1,Num2>extends true?true:IsLowerThan<Num1,Num2>;
973
- /** -------------------------------------------------------
974
- * * ***Utility Type: `IfLowerOrEqual`.***
975
- * -------------------------------------------------------
976
- * **Returns the third argument if the first argument (integer) is lower than
977
- * the second argument (integer) or equal (defaults to `true`), otherwise returns
978
- * the fourth argument (defaults to `false`).**
979
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
980
- * @template Num1 - The first integer to compare.
981
- * @template Num2 - The second integer to compare.
982
- * @template IfTrue - Value to return if `Num1 <= Num2`.
983
- * @template IfFalse - Value to return if `Num1 > Num2`.
984
- * @example
985
- * type Case1 = IfLowerOrEqual<1, 10, 'valid'>;
986
- * // ➔ 'valid'
987
- * type Case2 = IfLowerOrEqual<23, 1, 'valid', 'invalid'>;
988
- * // ➔ 'invalid'
989
- */
990
- type IfLowerOrEqual<Num1 extends number,Num2 extends number,IfTrue=true,IfFalse=false>=If<IsEqual<Num1,Num2>extends true?true:IsLowerThan<Num1,Num2>,IfTrue,IfFalse>;
991
- /** -------------------------------------------------------
992
- * * ***Utility Type: `IsGreaterThan`.***
993
- * -------------------------------------------------------
994
- * **Returns a boolean indicating whether the first integer
995
- * is ***greater than*** the second integer.**
996
- * - **Behavior:**
997
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
998
- * @template Num1 - The first integer.
999
- * @template Num2 - The second integer.
1000
- * @example
1001
- * ```ts
1002
- * type A = IsGreaterThan<10, 1>; // ➔ true
1003
- * type B = IsGreaterThan<-10, 1>; // ➔ false
1004
- * ```
1005
- */
1006
- type IsGreaterThan<Num1 extends number,Num2 extends number>=IsLowerThan<Num2,Num1>;
1007
- /** -------------------------------------------------------
1008
- * * ***Utility Type: `IfGreaterThan`.***
1009
- * -------------------------------------------------------
1010
- * - **Conditional:**
1011
- * - Returns the third argument if the first integer is ***greater than*** the
1012
- * second integer, otherwise returns the fourth argument.
1013
- * - **Behavior:**
1014
- * - Defaults: `IfTrue = true`, `IfFalse = false`.
1015
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1016
- * @template Num1 - The first integer.
1017
- * @template Num2 - The second integer.
1018
- * @template IfTrue - The branch type if condition is met. (default: `true`)
1019
- * @template IfFalse - The branch type if condition is not met. (default: `false`)
1020
- * @example
1021
- * ```ts
1022
- * type A = IfGreaterThan<10, 1, "valid">;
1023
- * // ➔ "valid"
1024
- * type B = IfGreaterThan<-10, 1, "valid", "invalid">;
1025
- * // ➔ "invalid"
1026
- * ```
1027
- */
1028
- type IfGreaterThan<Num1 extends number,Num2 extends number,IfTrue=true,IfFalse=false>=IfLowerThan<Num2,Num1,IfTrue,IfFalse>;
1029
- /** -------------------------------------------------------
1030
- * * ***Utility Type: `IsGreaterOrEqual`.***
1031
- * -------------------------------------------------------
1032
- * **Returns a boolean indicating whether the first integer
1033
- * is ***greater than or equal*** to the second integer.**
1034
- * - **Behavior:**
1035
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1036
- * @template Num1 - The first integer.
1037
- * @template Num2 - The second integer.
1038
- * @example
1039
- * ```ts
1040
- * type A = IsGreaterOrEqual<10, 1>; // ➔ true
1041
- * type B = IsGreaterOrEqual<-10, 1>; // ➔ false
1042
- * type C = IsGreaterOrEqual<10, 10>; // ➔ true
1043
- * ```
1044
- */
1045
- type IsGreaterOrEqual<Num1 extends number,Num2 extends number>=IsEqual<Num1,Num2>extends true?true:IsGreaterThan<Num1,Num2>;
1046
- /** -------------------------------------------------------
1047
- * * ***Utility Type: `IfGreaterOrEqual`.***
1048
- * -------------------------------------------------------
1049
- * - **Conditional:**
1050
- * - Returns the third argument if the first integer is ***greater than or
1051
- * equal*** to the second integer, otherwise returns the fourth argument.
1052
- * - **Behavior:**
1053
- * - Defaults: `IfTrue = true`, `IfFalse = false`.
1054
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1055
- * @template Num1 - The first integer.
1056
- * @template Num2 - The second integer.
1057
- * @template IfTrue - The branch type if condition is met. (default: `true`)
1058
- * @template IfFalse - The branch type if condition is not met. (default: `false`)
1059
- * @example
1060
- * ```ts
1061
- * type A = IfGreaterOrEqual<10, 1, "valid">;
1062
- * // ➔ "valid"
1063
- * type B = IfGreaterOrEqual<-10, 1, "valid", "invalid">;
1064
- * // ➔ "invalid"
1065
- * type C = IfGreaterOrEqual<10, 10, "yes", "no">;
1066
- * // ➔ "yes"
1067
- * ```
1068
- */
1069
- type IfGreaterOrEqual<Num1 extends number,Num2 extends number,IfTrue=true,IfFalse=false>=If<IsEqual<Num1,Num2>extends true?true:IsGreaterThan<Num1,Num2>,IfTrue,IfFalse>;
1070
- /** ---------------------------------------------------------------------------
1071
- * * ***Type Options for {@link IsBetween | `IsBetween`}.***
1072
- * ---------------------------------------------------------------------------
1073
- * **Options to configure whether the borders of the interval are included
1074
- * when using {@link IsBetween | **`IsBetween`**}.**
1075
- */
1076
- type IsBetweenOptions={
1077
- /** * ***Whether to include the lower border (`Min`) in the comparison.***
1078
- *
1079
- * - `true` ➔ include `Min` (**default**).
1080
- * - `false` ➔ exclude `Min`.
1081
- *
1082
- * @default true
1083
- */
1084
- minIncluded?:boolean;
1085
- /** * ***Whether to include the upper border (`Max`) in the comparison.***
1086
- *
1087
- * - `true` ➔ include `Max` (**default**).
1088
- * - `false` ➔ exclude `Max`.
1089
- *
1090
- * @default true
1091
- */
1092
- maxIncluded?:boolean;};
1093
- /** -------------------------------------------------------
1094
- * * ***Utility Type: `IsBetween`.***
1095
- * -------------------------------------------------------
1096
- * **Returns a boolean whether the first integer argument is between the second and the third integer argument, by default, borders of the interval are included, which can be modified by the second argument.**
1097
- * - **Behavior:**
1098
- * - `minIncluded`, `maxIncluded` options show whether to include the lower and the higher borders
1099
- * respectively.
1100
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1101
- * @example
1102
- * type Case1 = IsBetween<1, 1, 10>;
1103
- * // ➔ true
1104
- * type Case2 = IsBetween<1, 1, 10, {minIncluded: false}>;
1105
- * // ➔ false
1106
- * type Case3 = IsBetween<10, 1, 10, {maxIncluded: false}>;
1107
- * // ➔ false
1108
- */
1109
- type IsBetween<Num extends number,Min extends number,Max extends number,Options extends IsBetweenOptions={minIncluded:true;maxIncluded:true;}>=IsEqual<Num,Min>extends true?Options["minIncluded"]:IsEqual<Num,Max>extends true?Options["maxIncluded"]:And<IsGreaterThan<Num,Min>,IsLowerThan<Num,Max>>;type _IsValidRGBParameter<T extends number>=IsInteger<T>extends true?IsBetween<T,0,255>:false;
1110
- /** * ***Configuration options for a type-level utility
1111
- * {@link RGB | `RGB`} | {@link IsRGB | `IsRGB` } | {@link IfRGB | `IfRGB` }.*** */
1112
- type RGBOptions={
1113
- /** * ***Separator character(s) used between the RGB components (`r`, `g`, `b`).***
1114
- *
1115
- * - **For example:**
1116
- * - `","` ➔ `"rgb(23,242,0)"`.
1117
- * - `", "` ➔ `"rgb(23, 242, 0)"`.
1118
- *
1119
- * @default ", "
1120
- */
1121
- separator:string;};
1122
- /** * ***Default configuration for the {@link RGBOptions | `RGBOptions`}.***
1123
- *
1124
- * @example
1125
- * ```ts
1126
- * type Opt = DefaultRGBOptions;
1127
- * // ➔ { separator: ", " }
1128
- * ```
1129
- */
1130
- type DefaultRGBOptions={
1131
- /** * ***Default separator for RGB components.***
1132
- *
1133
- * **Produces strings like `"rgb(23, 242, 0)"`.**
1134
- */
1135
- separator:", ";};
1136
- /** -------------------------------------------------------
1137
- * * ***Utility Type: `RGB`.***
1138
- * -------------------------------------------------------
1139
- * **A type-level utility that validates an **RGB color string**.**
1140
- * - **Behavior:**
1141
- * - Accepts `rgb(r, g, b)` format with customizable separators.
1142
- * - Each parameter `r`, `g`, `b` must be an integer between `0` and `255`.
1143
- * - Returns `T` if valid, otherwise `never`.
1144
- * @template T - A string to check.
1145
- * @template Options - Options with `separator` (defaults to `", "`).
1146
- * @example
1147
- * ```ts
1148
- * type A = RGB<"rgb(23, 242, 0)">;
1149
- * // ➔ "rgb(23, 242, 0)"
1150
- * type B = RGB<"rgb(324, 123, 3)">;
1151
- * // ➔ never
1152
- * type C = RGB<"rgb(23,242,0)", { separator: "," }>;
1153
- * // ➔ "rgb(23,242,0)"
1154
- * ```
1155
- */
1156
- type RGB<T extends string,Options extends RGBOptions=DefaultRGBOptions>=T extends`rgb(${infer R extends number}${Options["separator"]}${infer G extends number}${Options["separator"]}${infer B extends number})`?AndArr<[ _IsValidRGBParameter<R>,_IsValidRGBParameter<G>,_IsValidRGBParameter<B>]>extends true?T:never:never;
1157
- /** -------------------------------------------------------
1158
- * * ***Utility Type: `IsRGB`.***
1159
- * -------------------------------------------------------
1160
- * **A type-level utility that checks if a string is a valid **RGB color**.**
1161
- * - Returns `true` if valid, otherwise `false`.
1162
- * @template T - A string to check.
1163
- * @template Options - Options with `separator` (defaults to `", "`).
1164
- * @example
1165
- * ```ts
1166
- * type A = IsRGB<"rgb(23, 242, 0)">;
1167
- * // ➔ true
1168
- * type B = IsRGB<"rgb(324, 123, 3)">;
1169
- * // ➔ false
1170
- * type C = IsRGB<"rgb(23,242,0)", { separator: "," }>;
1171
- * // ➔ true
1172
- * ```
1173
- */
1174
- type IsRGB<T extends string,Options extends RGBOptions=DefaultRGBOptions>=Not<IsNever<RGB<T,Options>>>;
1175
- /** -------------------------------------------------------
1176
- * * ***Utility Type: `IfRGB`.***
1177
- * -------------------------------------------------------
1178
- * **A conditional type that returns `IfTrue` if `T` is a valid **RGB color**,
1179
- * otherwise returns `IfFalse`.**
1180
- * @template T - A string to check.
1181
- * @template IfTrue - Return type if valid (defaults to `true`).
1182
- * @template IfFalse - Return type if invalid (defaults to `false`).
1183
- * @template Options - Options with `separator` (defaults to `", "`).
1184
- * @example
1185
- * ```ts
1186
- * type A = IfRGB<"rgb(23, 242, 0)">;
1187
- * // ➔ true
1188
- * type B = IfRGB<"rgb(23, 242, 0)", "valid">;
1189
- * // ➔ "valid"
1190
- * type C = IfRGB<"rgb(324, 123, 3)", "valid", "invalid">;
1191
- * // ➔ "invalid"
1192
- * type D = IfRGB<"rgb(23,242,0)", true, false { separator: "," }>;
1193
- * // ➔ true
1194
- * ```
1195
- */
1196
- type IfRGB<T extends string,IfTrue=true,IfFalse=false,Options extends RGBOptions=DefaultRGBOptions>=If<IsRGB<T,Options>,IfTrue,IfFalse>;type _ValidHEXCharacters=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];type _AllowedHEXLength=3|4|6|8;
1197
- /** -------------------------------------------------------
1198
- * * ***Utility Type: `HEX`.***
1199
- * -------------------------------------------------------
1200
- * **A type-level utility that validates a **HEX color string**.**
1201
- * - **Behavior:**
1202
- * - Accepts `#RGB`, `#RGBA`, `#RRGGBB`, or `#RRGGBBAA` formats.
1203
- * - Characters must be `[0-9A-F]` (**case-insensitive**).
1204
- * - Returns `T` if valid, otherwise `never`.
1205
- * @template T - A string to check.
1206
- * @example
1207
- * ```ts
1208
- * type A = HEX<"#000">; // ➔ "#000"
1209
- * type B = HEX<"#g00">; // ➔ never
1210
- * type C = HEX<"#0000">; // ➔ "#0000"
1211
- * type D = HEX<"#00000">; // ➔ never
1212
- * type E = HEX<"#000000">; // ➔ "#000000"
1213
- * type F = HEX<"#00000000">; // ➔ "#00000000"
1214
- * ```
1215
- */
1216
- type HEX<T extends string>=(Uppercase<T>extends`#${infer HEXWithoutHashTag extends string}`?StringLength<HEXWithoutHashTag>extends _AllowedHEXLength?ExtendsArr<Split<HEXWithoutHashTag,"">,_ValidHEXCharacters[number]>:false:false)extends true?T:never;
1217
- /** -------------------------------------------------------
1218
- * * ***Utility Type: `IsHEX`.***
1219
- * -------------------------------------------------------
1220
- * **A type-level utility that checks if a string is a valid **HEX color**.**
1221
- * - Returns `true` if valid, otherwise `false`.
1222
- * @template T - A string to check.
1223
- * @example
1224
- * ```ts
1225
- * type A = IsHEX<"#000">; // ➔ true
1226
- * type B = IsHEX<"#g00">; // ➔ false
1227
- * ```
1228
- */
1229
- type IsHEX<T extends string>=Not<IsNever<HEX<T>>>;
1230
- /** -------------------------------------------------------
1231
- * * ***Utility Type: `IfHEX`.***
1232
- * -------------------------------------------------------
1233
- * **A conditional type that returns `IfTrue` if `T` is a valid **HEX color**,
1234
- * otherwise returns `IfFalse`.**
1235
- * @template T - A string to check.
1236
- * @template IfTrue - Return type if valid (defaults to `true`).
1237
- * @template IfFalse - Return type if invalid (defaults to `false`).
1238
- * @example
1239
- * ```ts
1240
- * type A = IfHEX<"#000">;
1241
- * // ➔ true
1242
- * type B = IfHEX<"#g00">;
1243
- * // ➔ false
1244
- * type C = IfHEX<"#0000", "valid">;
1245
- * // ➔ "valid"
1246
- * type D = IfHEX<"#00000", "valid","invalid">;
1247
- * // ➔ "invalid"
1248
- * ```
1249
- */
1250
- type IfHEX<T extends string,IfTrue=true,IfFalse=false>=If<IsHEX<T>,IfTrue,IfFalse>;
1251
- /** * ***Configuration options for a type-level utility
1252
- * {@link HSL | `HSL` } | {@link IsHSL | `IsHSL` } | {@link IfHSL | `IfHSL` }.*** */
1253
- type HSLOptions={
1254
- /** * ***Separator character(s) used between the HSL components (`h`, `s`, `l`).***
1255
- *
1256
- * - **For example:**
1257
- * - `","` ➔ `"hsl(180,100%,50%)"`.
1258
- * - `", "` ➔ `"hsl(180, 100%, 50%)"`.
1259
- *
1260
- * @default ", "
1261
- */
1262
- separator:string;};
1263
- /** * ***Default configuration for the {@link HSLOptions | `HSLOptions`}.***
1264
- *
1265
- * @example
1266
- * ```ts
1267
- * type Opt = DefaultHSLOptions;
1268
- * // ➔ { separator: ", " }
1269
- * ```
1270
- */
1271
- type DefaultHSLOptions={
1272
- /** * ***Default separator for HSL components.***
1273
- *
1274
- * **Produces strings like `"hsl(180, 100%, 50%)"`.**
1275
- */
1276
- separator:", ";};
1277
- /** -------------------------------------------------------
1278
- * * ***Utility Type: `HSL`.***
1279
- * -------------------------------------------------------
1280
- * **A type-level utility that validates an **HSL color string**.**
1281
- * - **Behavior:**
1282
- * - Accepts `hsl(h, s%, l%)` format with customizable separators.
1283
- * - `h` must be an integer, `s` and `l` must be integers between `0` and `100`.
1284
- * - Returns `T` if valid, otherwise `never`.
1285
- * @template T - A string to check.
1286
- * @template Options - Options with `separator` (defaults to `", "`).
1287
- * @example
1288
- * ```ts
1289
- * type A = HSL<"hsl(100, 34%, 56%)">;
1290
- * // ➔ "hsl(100, 34%, 56%)"
1291
- * type B = HSL<"hsl(100, 200%, 3)">;
1292
- * // ➔ never
1293
- * type C = HSL<"hsl(100,34%,56%)", { separator: "," }>;
1294
- * // ➔ "hsl(100,34%,56%)"
1295
- * ```
1296
- */
1297
- type HSL<T extends string,Options extends HSLOptions=DefaultHSLOptions>=(T extends`hsl(${infer H extends number}${Options["separator"]}${infer S extends number}%${Options["separator"]}${infer L extends number}%)`?AndArr<[IsInteger<H>,IsInteger<S>,IsInteger<L>]>extends true?AndArr<[IsBetween<S,0,100>,IsBetween<L,0,100>]>:false:false)extends true?T:never;
1298
- /** -------------------------------------------------------
1299
- * * ***Utility Type: `IsHSL`.***
1300
- * -------------------------------------------------------
1301
- * **A type-level utility that checks if a string is a valid **HSL color**.**
1302
- * - Returns `true` if valid, otherwise `false`.
1303
- * @template T - A string to check.
1304
- * @template Options - Options with `separator` (defaults to `", "`).
1305
- * @example
1306
- * ```ts
1307
- * type A = IsHSL<"hsl(100, 34%, 56%)">;
1308
- * // ➔ true
1309
- * type B = IsHSL<"hsl(101, 200%, 3)">;
1310
- * // ➔ false
1311
- * type C = IsHSL<"hsl(100,34%,56%)", { separator: "," }>;
1312
- * // ➔ true
1313
- * ```
1314
- */
1315
- type IsHSL<T extends string,Options extends HSLOptions=DefaultHSLOptions>=Not<IsNever<HSL<T,Options>>>;
1316
- /** -------------------------------------------------------
1317
- * * ***Utility Type: `IfHSL`.***
1318
- * -------------------------------------------------------
1319
- * **A conditional type that returns `IfTrue` if `T` is a valid **HSL color**,
1320
- * otherwise returns `IfFalse`.**
1321
- * @template T - A string to check.
1322
- * @template IfTrue - Return type if valid (defaults to `true`).
1323
- * @template IfFalse - Return type if invalid (defaults to `false`).
1324
- * @template Options - Options with `separator` (defaults to `", "`).
1325
- * @example
1326
- * ```ts
1327
- * type A = IfHSL<"hsl(100, 34%, 56%)", "ok">;
1328
- * // ➔ "ok"
1329
- * type B = IfHSL<"hsl(101, 200%, 3)", "ok", "fail">;
1330
- * // ➔ "fail"
1331
- * type C = IfHSL<"hsl(100,34%,56%)", true, false, { separator: "," }>;
1332
- * // ➔ true
1333
- * ```
1334
- */
1335
- type IfHSL<T extends string,IfTrue=true,IfFalse=false,Options extends HSLOptions=DefaultHSLOptions>=If<IsHSL<T,Options>,IfTrue,IfFalse>;
1336
- /** * ***High-level configuration for {@link Color | `Color`} parsing utilities.***
1337
- *
1338
- * **Allows customizing **RGB** and **HSL** parsing behavior independently.**
1339
- */
1340
- type ColorOptions={
1341
- /** * ***Options for handling RGB color strings.***
1342
- *
1343
- * - **Behavior:**
1344
- * - Controls parsing and formatting behavior of RGB values.
1345
- * - By default uses {@link DefaultRGBOptions | **`DefaultRGBOptions`**}.
1346
- * @default DefaultRGBOptions
1347
- * @example
1348
- * ```ts
1349
- * type Opt = ColorOptions["rgbOptions"];
1350
- * // ➔ { separator: string }
1351
- *
1352
- * // with defaults applied:
1353
- * type Opt = DefaultRGBOptions;
1354
- * // ➔ { separator: ", " }
1355
- * ```
1356
- */
1357
- rgbOptions?:RGBOptions;
1358
- /** * ***Options for handling HSL color strings.***
1359
- *
1360
- * - **Behavior:**
1361
- * - Controls parsing and formatting behavior of HSL values.
1362
- * - By default uses {@link DefaultHSLOptions | **`DefaultHSLOptions`**}.
1363
- * @default DefaultHSLOptions
1364
- * @example
1365
- * ```ts
1366
- * type Opt = ColorOptions["hslOptions"];
1367
- * // ➔ { separator: string }
1368
- *
1369
- * // with defaults applied:
1370
- * type Opt = DefaultHSLOptions;
1371
- * // ➔ { separator: ", " }
1372
- * ```
1373
- */
1374
- hslOptions?:HSLOptions;};
1375
- /** * ***Default configuration for the {@link ColorOptions |`ColorOptions`}.***
1376
- *
1377
- * @example
1378
- * ```ts
1379
- * type Opt = DefaultColorOptions;
1380
- * // ➔ { rgbOptions: { separator: ", " }, hslOptions: { separator: ", " } }
1381
- * ```
1382
- */
1383
- type DefaultColorOptions={
1384
- /** * ***Default configuration for `RGBOptions`.***
1385
- *
1386
- * - **Behavior:**
1387
- * - Provides the default separator for RGB strings.
1388
- * - By default: `", "`
1389
- * @example
1390
- * ```ts
1391
- * type RGBOpt = DefaultColorOptions["rgbOptions"];
1392
- * // ➔ { separator: ", " }
1393
- * ```
1394
- */
1395
- rgbOptions:DefaultRGBOptions;
1396
- /** * ***Default configuration for `HSLOptions`.***
1397
- *
1398
- * - **Behavior:**
1399
- * - Provides the default separator for HSL strings.
1400
- * - By default: `", "`
1401
- * @example
1402
- * ```ts
1403
- * type HSLOpt = DefaultColorOptions["hslOptions"];
1404
- * // ➔ { separator: ", " }
1405
- * ```
1406
- */
1407
- hslOptions:DefaultHSLOptions;};type ResolveRGBOptions<O extends ColorOptions>=O["rgbOptions"] extends RGBOptions?O["rgbOptions"]:DefaultRGBOptions;type ResolveHSLOptions<O extends ColorOptions>=O["hslOptions"] extends HSLOptions?O["hslOptions"]:DefaultHSLOptions;
1408
- /** -------------------------------------------------------
1409
- * * ***Utility Type: `Color`.***
1410
- * -------------------------------------------------------
1411
- * - **A type-level utility that validates a string as a **Color** in:**
1412
- * - **`RGB`**.
1413
- * - **`HEX`**.
1414
- * - **`HSL`**.
1415
- * @returns {T} Returns `T` if valid, otherwise `never`.
1416
- * @template T - A string to check.
1417
- * @template Options - Options to pass down to `RGB`/`HSL` validation.
1418
- * @example
1419
- * ```ts
1420
- * type A = Color<"rgb(23, 242, 0)">;
1421
- * // ➔ "rgb(23, 242, 0)"
1422
- * type B = Color<"rgb(324, 123, 3)">;
1423
- * // ➔ never
1424
- * type C = Color<"#000000">;
1425
- * // ➔ "#000000"
1426
- * type D = Color<"hsl(100,34%,56%)", { hslOptions: { separator: "," }}>;
1427
- * // ➔ "hsl(100,34%,56%)"
1428
- * ```
1429
- */
1430
- type Color<T extends string,Options extends ColorOptions=DefaultColorOptions>=HEX<T>|HSL<T,ResolveHSLOptions<Options>>|RGB<T,ResolveRGBOptions<Options>>;
1431
- /** -------------------------------------------------------
1432
- * * ***Utility Type: `IsColor`.***
1433
- * -------------------------------------------------------
1434
- * **A type-level utility that checks if a string is a valid **Color**
1435
- * (`RGB` | `HEX` | `HSL`).**
1436
- * @returns {T} - Returns `true` if valid, otherwise `false`.
1437
- * @template T - A string to check.
1438
- * @template Options - Options to pass down to RGB/HSL validation.
1439
- * @example
1440
- * ```ts
1441
- * type A = IsColor<"rgb(23, 242, 0)">;
1442
- * // ➔ true
1443
- * type B = IsColor<"rgb(324, 123, 3)">;
1444
- * // ➔ false
1445
- * type C = IsColor<"#000000">;
1446
- * // ➔ true
1447
- * type D = IsColor<"hsl(100,34%,56%)", { hslOptions: { separator: "," } }>;
1448
- * // ➔ true
1449
- * ```
1450
- */
1451
- type IsColor<T extends string,Options extends ColorOptions=DefaultColorOptions>=Not<IsNever<Color<T,Options>>>;
1452
- /** -------------------------------------------------------
1453
- * * ***Utility Type: `IfColor`.***
1454
- * -------------------------------------------------------
1455
- * **A conditional type that returns `IfTrue` if `T` is a valid **Color**
1456
- * (`RGB` | `HEX` | `HSL`), otherwise returns `IfFalse`.**
1457
- * @template T - A string to check.
1458
- * @template IfTrue - Return type if valid (defaults to `true`).
1459
- * @template IfFalse - Return type if invalid (defaults to `false`).
1460
- * @template Options - Options to pass down to RGB/HSL validation.
1461
- * @example
1462
- * ```ts
1463
- * type A = IfColor<"rgb(23, 242, 0)", { rgbOptions: { separator: ", " }}, "valid">;
1464
- * // ➔ "valid"
1465
- * type B = IfColor<"rgb(324, 123, 3)", DefaultColorOptions, "valid","invalid">;
1466
- * // ➔ "invalid"
1467
- * type C = IfColor<"#000000">;
1468
- * // ➔ true
1469
- * ```
1470
- */
1471
- type IfColor<T extends string,Options extends ColorOptions=DefaultColorOptions,IfTrue=true,IfFalse=false>=If<IsColor<T,Options>,IfTrue,IfFalse>;
1472
- /** -------------------------------------------------------
1473
- * * ***Utility Type: `Concat`.***
1474
- * -------------------------------------------------------
1475
- * **A type-level utility that concatenates `two arrays` into `one`.**
1476
- * @template T - The first array type.
1477
- * @template U - The second array type, or a single element.
1478
- * @example
1479
- * ```ts
1480
- * type A = Concat<[number, number], [string, string]>;
1481
- * // ➔ [number, number, string, string]
1482
- * type B = Concat<[], [1, 2]>;
1483
- * // ➔ [1, 2]
1484
- * type C = Concat<[1, 2], 3>;
1485
- * // ➔ [1, 2, 3]
1486
- * type D = Concat<[], 5>;
1487
- * // ➔ [5]
1488
- * type E = Concat<[1, 2], []>;
1489
- * // ➔ [1, 2]
1490
- * ```
1491
- */
1492
- type Concat<T extends readonly unknown[],U>=[ ...T,...(U extends readonly unknown[]?U:[U])];
1493
- /** -------------------------------------------------------
1494
- * * ***Utility Type: `DigitsTuple`.***
1495
- * -------------------------------------------------------
1496
- * **A **type-level utility** that converts a numeric literal (number or bigint) into
1497
- * a structured representation of its digits.**
1498
- * - **The resulting type is an **object** with the following properties:**
1499
- * - `negative`: boolean flag indicating if the number is negative.
1500
- * - `bigint`: boolean flag indicating if the value is a bigint.
1501
- * - `float`: boolean flag indicating if the value is a floating-point number.
1502
- * - `digits`: a tuple of digits (each as a `number`), with decimal points and
1503
- * bigint suffix `n` removed.
1504
- * - **Works with:**
1505
- * - Positive integers
1506
- * - Negative integers
1507
- * - Zero and negative zero
1508
- * - Floating-point numbers (decimal points are ignored)
1509
- * - BigInt values
1510
- * **Note:** TypeScript automatically normalizes scientific notation numeric literals
1511
- * (e.g., `5e3` ➔ `5000`), so the `digits` tuple will reflect the expanded value.
1512
- * @template T - A numeric literal type (`number` or `bigint`) to convert.
1513
- * @example
1514
- * ```ts
1515
- * // Single digit
1516
- * type A = DigitsTuple<1>;
1517
- * // ➔ { negative: false; bigint: false; float: false; digits: [1] }
1518
- *
1519
- * // Positive integer
1520
- * type B = DigitsTuple<123>;
1521
- * // ➔ { negative: false; bigint: false; float: false; digits: [1, 2, 3] }
1522
- *
1523
- * // Negative integer
1524
- * type C = DigitsTuple<-123>;
1525
- * // ➔ { negative: true; bigint: false; float: false; digits: [1, 2, 3] }
1526
- *
1527
- * // Zero and negative zero (treated the same)
1528
- * type D = DigitsTuple<0>;
1529
- * // ➔ { negative: false; bigint: false; float: false; digits: [0] }
1530
- * type E = DigitsTuple<-0>;
1531
- * // ➔ { negative: false; bigint: false; float: false; digits: [0] }
1532
- *
1533
- * // Floating-point numbers
1534
- * type F = DigitsTuple<0.123>;
1535
- * // ➔ { negative: false; bigint: false; float: true; digits: [0, 1, 2, 3] }
1536
- * type G = DigitsTuple<-0.123>;
1537
- * // ➔ { negative: true; bigint: false; float: true; digits: [0, 1, 2, 3] }
1538
- *
1539
- * // BigInt values
1540
- * type H = DigitsTuple<98765n>;
1541
- * // ➔ { negative: false; bigint: true; float: false; digits: [9, 8, 7, 6, 5] }
1542
- * type I = DigitsTuple<-98765n>;
1543
- * // ➔ { negative: true; bigint: true; float: false; digits: [9, 8, 7, 6, 5] }
1544
- *
1545
- * // Scientific notation numeric literals (auto-expanded)
1546
- * type J = DigitsTuple<5e3>; // `5e3` is same like `5000`
1547
- * // ➔ { negative: false; bigint: false; float: false; digits: [5, 0, 0, 0] }
1548
- * type K = DigitsTuple<-2.5e2>; // `-2.5e2` is same like `-250`
1549
- * // ➔ { negative: true; bigint: false; float: true; digits: [2, 5, 0] }
1550
- * ```
1551
- */
1552
- type DigitsTuple<T extends number|bigint>={negative:`${T}`extends`-${string}`?true:false;float:IsFloat<Extract<T,number>>extends true?true:false;bigint:T extends bigint?true:false;digits:Split<ReplaceAll<Stringify<Abs<T>>,[".","n"],"">>extends infer R?{[K in keyof R]:R[K] extends string?ParseNumber<R[K]>:never;}:never;};
1553
- /** -------------------------------------------------------
1554
- * * ***Utility Type: `ReturnItselfIfExtends`.***
1555
- * -------------------------------------------------------
1556
- * **This utility is useful when you want to **narrow types by extension**,
1557
- * replacing them with a fallback if they match a given base constraint,
1558
- * while preserving them otherwise.**
1559
- * - **A conditional type that returns:**
1560
- * - `Else` if `T` extends `Base`.
1561
- * - `T` itself if `T` does extend `Base`.
1562
- * - `IfANever` if `T` is `never`.
1563
- * @template T - The type to check.
1564
- * @template Base - The base type to test against.
1565
- * @template Else - The type to return if `T` extends `Base`.
1566
- * @template IfANever - The type to return if `T` or `Base` is `never` (default: `never`).
1567
- * @example
1568
- * ```ts
1569
- * type Case1 = ReturnItselfIfExtends<1, number, 2>
1570
- * // ➔ 1
1571
- *
1572
- * type Case2 = ReturnItselfIfExtends<'1', number, 2>
1573
- * // ➔ 2
1574
- *
1575
- * // ℹ️ Never Case:
1576
- * type Case3 = ReturnItselfIfExtends<never, string, 0>
1577
- * // ➔ never
1578
- *
1579
- * type Case4 = ReturnItselfIfExtends<string, never, 0, undefined>
1580
- * // ➔ undefined
1581
- * ```
1582
- */
1583
- type ReturnItselfIfExtends<T,Base,Else,IfANever=never>=IfNever<If<Extends<Or<Base,T>,true>,never>,IfANever,T extends Base?T:Else>;
1584
- /** -------------------------------------------------------
1585
- * * ***Utility Type: `ReturnItselfIfNotExtends`.***
1586
- * -------------------------------------------------------
1587
- * **This utility is useful for preserving a type unless it matches
1588
- * a broader constraint, in which case it is replaced with a fallback.**
1589
- * - **A conditional type that returns:**
1590
- * - `Else` if `T` extends `Base`.
1591
- * - `T` itself if `T` does **not** extend `Base`.
1592
- * - `IfANever` if `T` is `never`.
1593
- * @template T - The type to check.
1594
- * @template Base - The base type to test against.
1595
- * @template Else - The type to return if `T` extends `Base`.
1596
- * @template IfANever - The type to return if `T` or `Base` is `never` (default: `never`).
1597
- * @example
1598
- * ```ts
1599
- * type Case1 = ReturnItselfIfNotExtends<'1', number, 2>
1600
- * // ➔ '1'
1601
- * type Case2 = ReturnItselfIfNotExtends<1, number, 2>
1602
- * // ➔ 2
1603
- *
1604
- * // ℹ️ Never Case:
1605
- * type Case3 = ReturnItselfIfNotExtends<never, string, 0>;
1606
- * // ➔ never
1607
- * type Case4 = ReturnItselfIfNotExtends<string, never, 0, undefined>;
1608
- * // ➔ undefined
1609
- * ```
1610
- */
1611
- type ReturnItselfIfNotExtends<T,Base,Else,IfANever=never>=IfNever<If<Extends<Or<Base,T>,true>,never>,IfANever,T extends Base?Else:T>;type MultiplicationMap={0:[0,0,0,0,0,0,0,0,0,0];1:[0,1,2,3,4,5,6,7,8,9];2:[0,2,4,6,8,10,12,14,16,18];3:[0,3,6,9,12,15,18,21,24,27];4:[0,4,8,12,16,20,24,28,32,36];5:[0,5,10,15,20,25,30,35,40,45];6:[0,6,12,18,24,30,36,42,48,54];7:[0,7,14,21,28,35,42,49,56,63];8:[0,8,16,24,32,40,48,56,64,72];9:[0,9,18,27,36,45,54,63,72,81];};type _MultiSingle<Num1 extends string,DigitOfNum2 extends keyof MultiplicationMap,Carry extends number=0,Result extends string="">=IsEmptyString<Num1>extends true?ReturnItselfIfNotExtends<RemoveLeading<`${Carry}${Result}`,"0">,"","0">:IsEqual<Num1,0>extends true?"0":IsEqual<DigitOfNum2,0>extends true?"0":LastCharacter<Num1,{includeRest:true;}>extends [ infer Num1LastCharacter extends string,infer Num1Rest extends string]?Stringify<Sum<MultiplicationMap[DigitOfNum2][ParseNumber<Num1LastCharacter>& keyof MultiplicationMap[DigitOfNum2]],Carry>>extends infer Multiplied extends string?LastCharacter<Multiplied,{includeRest:true;}>extends [ infer MultipliedLastDigit extends string,infer MultipliedRest extends string]?_MultiSingle<Num1Rest,DigitOfNum2,If<IsNever<ParseNumber<MultipliedRest>>,0,ParseNumber<MultipliedRest>>,`${MultipliedLastDigit}${Result}`>:never:never:never;type _Multi<Num1 extends string,Num2 extends string,Result extends string="",Iteration extends unknown[]=[]>=IsEmptyString<Num2>extends true?Result:LastCharacter<Num2,{includeRest:true;}>extends [ infer Num2LastCharacter extends string,infer Num2Rest extends string]?ParseNumber<Num2LastCharacter>extends infer Num2Digit extends keyof MultiplicationMap?_Multi<Num1,Num2Rest,Stringify<_Sum<Result,ReturnItselfIfNotExtends<RemoveLeading<`${_MultiSingle<Num1, Num2Digit>}${Repeat<"0", Iteration["length"]>}`,"0">,"","0">>>,Push<Iteration,unknown>>:never:Result;
1612
- /** -------------------------------------------------------
1613
- * * ***Utility Type: `Multi`.***
1614
- * -------------------------------------------------------
1615
- * **Accepts two integers and returns their **multiplication**.**
1616
- * - **Behavior:**
1617
- * - Handles negative numbers automatically.
1618
- * - Uses internal type-level recursion to simulate multiplication of
1619
- * digit strings.
1620
- * - Works with integers within the range:
1621
- * - `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1622
- * @template Num1 - The first integer (can be negative).
1623
- * @template Num2 - The second integer (can be negative).
1624
- * @example
1625
- * ```ts
1626
- * type Case1 = Multi<10, 0>; // ➔ 0
1627
- * type Case2 = Multi<4, 6>; // ➔ 24
1628
- * type Case3 = Multi<-4, 6>; // ➔ -24
1629
- * type Case4 = Multi<-4, -6>; // ➔ 24
1630
- * type Case5 = Multi<123, 45>; // ➔ 5535
1631
- * ```
1632
- * @note
1633
- * - ***Internal helpers:***
1634
- * - `_Multi` ➔ Recursively multiplies digit strings and accumulates the result.
1635
- * - `_MultiSingle` ➔ Multiplies a string-number with a single digit, handling carry.
1636
- */
1637
- type Multi<Num1 extends number,Num2 extends number>=IsEqual<Num1,0>extends true?0:IsEqual<Num2,0>extends true?0:ParseNumber<_Multi<Stringify<Abs<Num1>>,Stringify<Abs<Num2>>>>extends infer Result extends number?IfNegative<Num1,IfNegative<Num2,Result,Negate<Result>>,IfNegative<Num2,Negate<Result>,Result>>:never;type _FindQuotient<Dividend extends number,Divisor extends number,CurrentQuotient extends number>=Multi<Divisor,CurrentQuotient>extends infer Product extends number?IsEqual<Dividend,Product>extends true?CurrentQuotient:IsLowerThan<Dividend,Product>extends true?_FindQuotient<Dividend,Divisor,Decrement<CurrentQuotient>>:CurrentQuotient:never;type _Div<Dividend extends string,Divisor extends number,Result extends string="",CurrentDividend extends string="",IterationsWithoutDivision extends number=0,HadFirstDivision extends boolean=false>=Or<IsEmptyString<CurrentDividend>,IsLowerThan<ParseNumber<CurrentDividend>,Divisor>>extends true?IsEmptyString<Dividend>extends true?ParseNumber<If<And<HadFirstDivision,IsNotEqual<IterationsWithoutDivision,0>>,`${Result}0`,Result>>:Dividend extends`${infer FirstDigit extends string}${infer Rest extends string}`?_Div<Rest,Divisor,If<And<HadFirstDivision,IsNotEqual<IterationsWithoutDivision,0>>,`${Result}0`,Result>,IfEqual<CurrentDividend,"0",FirstDigit,`${CurrentDividend}${FirstDigit}`>,Increment<IterationsWithoutDivision>,HadFirstDivision>:never:_FindQuotient<ParseNumber<CurrentDividend>,Divisor,10>extends infer Quotient extends number?IsNever<Quotient>extends true?ParseNumber<Result>:Sub<ParseNumber<CurrentDividend>,Multi<Quotient,Divisor>>extends infer Remainder extends number?_Div<Dividend,Divisor,`${Result}${Quotient}`,IfGreaterThan<Remainder,0,`${Remainder}`,"">,0,true>:never:never;
1638
- /** -------------------------------------------------------
1639
- * * ***Utility Type: `Div`.***
1640
- * -------------------------------------------------------
1641
- * **A type-level utility that returns the integer division of two numbers.
1642
- * Handles negative numbers correctly and returns `never` if dividing by zero.**
1643
- * - **Behavior:**
1644
- * - Returns `0` if the absolute value of dividend is smaller than divisor.
1645
- * - Preserves the sign according to standard integer division rules.
1646
- * @template Dividend - The dividend number.
1647
- * @template Divisor - The divisor number.
1648
- * @example
1649
- * ```ts
1650
- * type A = Div<10, 2>; // ➔ 5
1651
- * type B = Div<7, 3>; // ➔ 2
1652
- * type C = Div<-7, 3>; // ➔ -2
1653
- * type D = Div<7, -3>; // ➔ -2
1654
- * type E = Div<-7, -3>; // ➔ 2
1655
- * type F = Div<2, 5>; // ➔ 0
1656
- * type G = Div<0, 5>; // ➔ 0
1657
- * type H = Div<5, 0>; // ➔ never
1658
- * ```
1659
- */
1660
- type Div<Dividend extends number,Divisor extends number>=IsEqual<Divisor,0>extends true?never:IsEqual<Dividend,0>extends true?0:IsEqual<Dividend,Divisor>extends true?1:IsLowerThan<Abs<Dividend>,Abs<Divisor>>extends true?0:_Div<Stringify<Abs<Dividend>>,Abs<Divisor>>extends infer Quotient extends number?If<Or<And<IsNegative<Dividend>,IsNegative<Divisor>>,And<IsPositive<Dividend>,IsPositive<Divisor>>>,Quotient,Negate<Quotient>>:never;
1661
- /** -------------------------------------------------------
1662
- * * ***Utility Type: `Dot`.***
1663
- * -------------------------------------------------------
1664
- * **A type-level utility that concatenates two string literals with a `.`.**
1665
- * - **Behavior:**
1666
- * - If the `Trims` flag is `true` (default), leading and trailing spaces in
1667
- * both strings are trimmed before concatenation.
1668
- * - If the second string literal is empty, it returns the first string literal.
1669
- * - If the first string literal is empty, it returns the second string literal.
1670
- * - Otherwise, it returns `${T}.${U}` (trimmed if `Trims` is `true`).
1671
- * @template T - The first string literal.
1672
- * @template U - The second string literal.
1673
- * @template Trims - Whether to trim whitespace from the inputs before concatenation (default: `true`).
1674
- * @example
1675
- * ```ts
1676
- * type A = Dot<"foo", "bar">;
1677
- * // ➔ "foo.bar"
1678
- * type B = Dot<"foo", "">;
1679
- * // ➔ "foo"
1680
- * type C = Dot<"", "baz">;
1681
- * // ➔ "baz"
1682
- * type D = Dot<" hello ", " world ", true>;
1683
- * // ➔ "hello.world"
1684
- * type E = Dot<" hello ", " world ", false>;
1685
- * // ➔ " hello . world "
1686
- * ```
1687
- */
1688
- type Dot<T extends string,U extends string,Trims extends boolean=true>=Extends<Trims,true>extends true?""extends Trim<U>?Trim<T>:""extends Trim<T>?`${Trim<U>}`:`${Trim<T>}.${Trim<U>}`:""extends U?T:`${T}.${U}`;
1689
- /** -------------------------------------------------------
1690
- * * ***Utility Type: `DotArray`.***
1691
- * -------------------------------------------------------
1692
- * **A type-level utility that concatenates an array of string literals with a `.`.**
1693
- * - **Behavior:**
1694
- * - Skips empty strings in the array.
1695
- * - If `Trims` is `true` (default), trims whitespace from each element.
1696
- * - Returns a single string literal.
1697
- * @template Arr - An array of string literals.
1698
- * @template Trims - Whether to trim whitespace from each element (default: `true`).
1699
- * @example
1700
- * ```ts
1701
- * type A = DotArray<["foo", "bar", "baz"]>;
1702
- * // ➔ "foo.bar.baz"
1703
- * type B = DotArray<["foo", "", "baz"]>;
1704
- * // ➔ "foo.baz"
1705
- * type C = DotArray<[" foo ", " bar "], true>;
1706
- * // ➔ "foo.bar"
1707
- * type D = DotArray<[" foo ", " bar "], false>;
1708
- * // ➔ " foo . bar "
1709
- * type E = DotArray<[]>;
1710
- * // ➔ ""
1711
- * ```
1712
- */
1713
- type DotArray<Arr extends string[],Trims extends boolean=true>=Arr extends [ infer Head extends string,...infer Tail extends string[]]?Head extends""?DotArray<Tail,Trims>:`${Trims extends true ? Trim<Head> : Head}${Tail extends [] ? "" : `.${DotArray<Tail,Trims>}`}`:"";
1714
- /** -------------------------------------------------------
1715
- * * ***Utility Type: `EndsWith`.***
1716
- * -------------------------------------------------------
1717
- * **A type-level utility that returns a boolean indicating
1718
- * whether the first string literal ends with the ***second one***.**
1719
- * @template T - The string to check.
1720
- * @template C - The ***ending string*** to match.
1721
- * @example
1722
- * ```ts
1723
- * type A = EndsWith<"Hello", "lo">; // ➔ true
1724
- * type B = EndsWith<"Foobar", "bar">; // ➔ true
1725
- * type C = EndsWith<"Foobar", "foo">; // ➔ false
1726
- * type D = EndsWith<"Hello", "world">; // ➔ false
1727
- * ```
1728
- */
1729
- type EndsWith<T extends string,C extends string>=T extends`${infer _}${C}`?true:false;
1730
- /** --------------------------------------------------
1731
- * * ***Utility Type: `ExcludeStrict`.***
1732
- * --------------------------------------------------
1733
- * **Performs a stricter version of `Exclude<T, U>` with improved type narrowing.**
1734
- * - ✅ Especially useful in generic libraries or utility types
1735
- * where standard `Exclude` may collapse or widen types unintentionally.
1736
- * @template T - The full union or set of types.
1737
- * @template U - The type(s) to be excluded from `T`.
1738
- * @example
1739
- * ```ts
1740
- * type A = 'a' | 'b' | 'c';
1741
- * type B = ExcludeStrict<A, 'b'>;
1742
- * // ➔ 'a' | 'c'
1743
- * ```
1744
- */
1745
- type ExcludeStrict<T,U extends T>=T extends unknown?0 extends(U extends T?([T] extends [U]?0:never):never)?never:T:never;type _Factorial<T extends number,CurrentNum extends number=1,CurrentProduct extends number=1>=IsEqual<T,CurrentNum>extends true?Multi<CurrentProduct,CurrentNum>:_Factorial<T,Increment<CurrentNum>,Multi<CurrentProduct,CurrentNum>>;
1746
- /** -------------------------------------------------------
1747
- * * ***Utility Type: `Factorial`.***
1748
- * -------------------------------------------------------
1749
- * **Accepts an integer argument and returns its ***mathematical factorial***.**
1750
- * - **Behavior:**
1751
- * - Valid range: `[0, 21]`.
1752
- * - Negative numbers or `number` type result in `never`.
1753
- * @template T - The integer to compute factorial for.
1754
- * @example
1755
- * ```ts
1756
- * type A = Factorial<0>;
1757
- * // ➔ 1
1758
- * type B = Factorial<6>;
1759
- * // ➔ 720
1760
- * type C = Factorial<-5>;
1761
- * // ➔ never
1762
- * type D = Factorial<number>;
1763
- * // ➔ never
1764
- * ```
1765
- */
1766
- type Factorial<T extends number>=number extends T?never:IsNegative<T>extends true?never:IsEqual<T,0>extends true?1:_Factorial<T>;
1767
- /** -------------------------------------------------------
1768
- * * ***Utility Type: `Fibonacci`.***
1769
- * -------------------------------------------------------
1770
- * **A type-level utility that computes the ***Fibonacci number*** at a given
1771
- * index `T`.**
1772
- * - **Behavior:**
1773
- * - Returns `never` for negative numbers.
1774
- * - Supports indices in the range `[0, 78]` due to TypeScript recursion limits.
1775
- * @template T - The index of the Fibonacci sequence.
1776
- * @example
1777
- * ```ts
1778
- * type A = Fibonacci<0>; // ➔ 0
1779
- * type B = Fibonacci<1>; // ➔ 1
1780
- * type C = Fibonacci<4>; // ➔ 3
1781
- * type D = Fibonacci<10>; // ➔ 55
1782
- * type E = Fibonacci<40>; // ➔ 102334155
1783
- * type D = Fibonacci<number>; // ➔ never
1784
- * ```
1785
- */
1786
- type Fibonacci<T extends number>=IsNegative<T>extends true?never:IsLowerThan<T,2>extends true?T:Fibonacci<Decrement<T>>extends infer NMinusOne extends number?Fibonacci<Sub<T,2>>extends infer NMinusTwo extends number?Sum<NMinusOne,NMinusTwo>:never:never;
1787
- /** ---------------------------------------------------------------------------
1788
- * * ***Type Options for {@link FirstCharacter | `FirstCharacter`}.***
1789
- * ---------------------------------------------------------------------------
1790
- * **Configuration options for the {@link FirstCharacter | `FirstCharacter`} type-level utility.**
1791
- */
1792
- type FirstCharacterOptions={
1793
- /** * ***Whether to include the rest of the string in the result tuple.***
1794
- *
1795
- * - **Behavior:**
1796
- * - `true` ➔ returns `[first character, rest of string]`.
1797
- * - `false` ➔ returns only the first character.
1798
- * @default false
1799
- * @example
1800
- * ```ts
1801
- * type Opt = { includeRest: true };
1802
- * type R = FirstCharacter<"abc", Opt>; // ➔ ["a", "bc"]
1803
- * ```
1804
- */
1805
- includeRest:boolean;};
1806
- /** -------------------------------------------------------
1807
- * * ***Utility Type: `FirstCharacter`.***
1808
- * -------------------------------------------------------
1809
- * **Accepts a string literal and returns its first character.**
1810
- * - **Behavior:**
1811
- * - If `Options["includeRest"]` is `true`, it returns a
1812
- * tuple: `[first character, rest of string]`.
1813
- * - Otherwise, it returns only the first character.
1814
- * @template T - The string literal to process.
1815
- * @template Options - Configuration options (default: `{ includeRest: false }`).
1816
- * - `includeRest: boolean` — Whether to include the rest of the string in a tuple.
1817
- * @example
1818
- * ```ts
1819
- * type A = FirstCharacter<"abc">;
1820
- * // ➔ "a"
1821
- * type B = FirstCharacter<"abc", { includeRest: true }>;
1822
- * // ➔ ["a", "bc"]
1823
- * type C = FirstCharacter<"">;
1824
- * // ➔ never
1825
- * type D = FirstCharacter<string>;
1826
- * // ➔ never
1827
- * ```
1828
- */
1829
- type FirstCharacter<T extends string,Options extends FirstCharacterOptions={includeRest:false;}>=T extends`${infer First extends string}${infer Rest extends string}`?If<Options["includeRest"],[First,Rest],First>:never;
1830
- /** -------------------------------------------------------
1831
- * * ***Utility Type: `FirstDigit`.***
1832
- * -------------------------------------------------------
1833
- * **Extracts the **first digit** of a given number `T`.**
1834
- * - **Behavior:**
1835
- * - Works with integers and decimals.
1836
- * - Handles negative numbers (`-123` ➔ `-1`).
1837
- * - Handles `0` and `-0` correctly (always returns `0`).
1838
- * - Works with bigint literals too.
1839
- * @template T - A number or bigint to extract the first digit from.
1840
- * @template Options - Optional settings.
1841
- * - `alwaysPositive?: boolean` (default: `false`)
1842
- * If `true`, the result is always positive regardless of the sign.
1843
- * @example
1844
- * ```ts
1845
- * type A = FirstDigit<0>; // ➔ 0
1846
- * type B = FirstDigit<-0>; // ➔ 0
1847
- * type C = FirstDigit<123>; // ➔ 1
1848
- * type D = FirstDigit<-123>; // ➔ -1
1849
- * type E = FirstDigit<0.123>; // ➔ 0
1850
- * type F = FirstDigit<-0.123>; // ➔ 0
1851
- * type G = FirstDigit<98765>; // ➔ 9
1852
- * type H = FirstDigit<-98765>; // ➔ -9
1853
- * type I = FirstDigit<-98765, {alwaysPositive:true}>; // ➔ 9
1854
- * ```
1855
- */
1856
- type FirstDigit<T extends number|bigint,Options extends{
1857
- /**
1858
- * If `true`, the result is always positive regardless of the sign, defaultValue: `false`.
1859
- * @example
1860
- * type I = FirstDigit<-98765, {alwaysPositive:true}>;
1861
- * // ➔ 9
1862
- *
1863
- * @default false
1864
- */
1865
- alwaysPositive?:boolean;}={alwaysPositive:false;}>=DigitsTuple<T>["digits"] extends readonly [infer First extends number,...unknown[]]?Options["alwaysPositive"] extends true?First:DigitsTuple<T>["negative"] extends true?Negate<First>:First:never;
1866
- /** -------------------------------------------------------
1867
- * * ***Utility Type: `Floor`.***
1868
- * -------------------------------------------------------
1869
- * **Type-level equivalent of `Math.floor()`.**
1870
- * - Returns the ***floored value*** of the passed number.
1871
- * @template T - A number type.
1872
- * @example
1873
- * ```ts
1874
- * type A = Floor<1.9>; // ➔ 1
1875
- * type B = Floor<-1.2>; // ➔ -2
1876
- * type C = Floor<3>; // ➔ 3
1877
- * type D = Floor<-5>; // ➔ -5
1878
- * ```
1879
- */
1880
- type Floor<T extends number>=IsFloat<T>extends true?GetFloatNumberParts<T>extends [infer Whole extends number,unknown]?IsNegative<T>extends true?Negate<Increment<Whole>>:Whole:never:T;
1881
- /** --------------------------------------------------
1882
- * * ***Utility Type: `Identity`.***
1883
- * --------------------------------------------------
1884
- * **Identity utility type that preserves the structure and inference of type `T`.**
1885
- * - ✅ Commonly used to force TypeScript to expand a mapped or intersection type
1886
- * into a more readable and usable shape.
1887
- * @template T - The type to preserve and normalize.
1888
- * @example
1889
- * ```ts
1890
- * type A = { a: string; b: number };
1891
- * type B = Identity<A>;
1892
- * // ➔ { a: string; b: number }
1893
- * ```
1894
- */
1895
- type Identity<T>={[P in keyof T]:T[P];};
1896
- /** ---------------------------------------------------------------------------
1897
- * * ***Type Options for {@link Shift | `Shift`}.***
1898
- * ---------------------------------------------------------------------------
1899
- */
1900
- type ShiftOptions={
1901
- /**
1902
- * If `true`, return both the rest of the array and the removed element
1903
- * as a tuple `[Rest, Removed]`.
1904
- *
1905
- * Default is `false`.
1906
- *
1907
- * @default false
1908
- */
1909
- includeRemoved:boolean;};
1910
- /** -------------------------------------------------------
1911
- * * ***Utility Type: `Shift`.***
1912
- * -------------------------------------------------------
1913
- * **Removes the first element from the array type `T`.**
1914
- * - **Behavior:**
1915
- * - By default (`includeRemoved: false`), returns the array without the first element.
1916
- * - If `includeRemoved: true`, returns a tuple `[Rest, Removed]`:
1917
- * - `Rest`: the remaining array.
1918
- * - `Removed`: the removed first element.
1919
- * @template T - The array type to operate on.
1920
- * @template Options - Optional flags. Default `{ includeRemoved: false }`.
1921
- * @example
1922
- * ```ts
1923
- * // Default: just remove first element
1924
- * type Case1 = Shift<[1, 2, 3]>;
1925
- * // ➔ [2, 3]
1926
- *
1927
- * // Include removed element
1928
- * type Case2 = Shift<[1, 2, 3], { includeRemoved: true }>;
1929
- * // ➔ [[2, 3], 1]
1930
- *
1931
- * // Empty array
1932
- * type Case3 = Shift<[]>;
1933
- * // ➔ never
1934
- * ```
1935
- */
1936
- type Shift<T extends readonly unknown[],Options extends ShiftOptions={includeRemoved:false;}>=T extends readonly [infer Removed,...infer Rest extends readonly unknown[]]?If<Options["includeRemoved"],[Rest,Removed],Rest>:never;
1937
- /** -------------------------------------------------------
1938
- * * ***Utility Type: `Includes`.***
1939
- * -------------------------------------------------------
1940
- * **Returns a boolean whether the second argument is in the first array argument.**
1941
- * @template T - The array to check.
1942
- * @template Pivot - The value to look for.
1943
- * @example
1944
- * ```ts
1945
- * type Case1 = Includes<[1, 2, 3], 1>; // ➔ true
1946
- * type Case2 = Includes<[1, 2, 3], 4>; // ➔ false
1947
- * ```
1948
- */
1949
- type Includes<T extends readonly unknown[],Pivot>=IsEmptyArray<T>extends true?false:Shift<T,{includeRemoved:true;}>extends [ infer Rest extends readonly unknown[],infer Removed]?IfEqual<Pivot,Removed,true,Includes<Rest,Pivot>>:false;type _IndexOfArray<T extends readonly unknown[],Pivot,Index extends number=0>=T extends readonly [infer First,...infer Rest extends unknown[]]?IsEqual<First,Pivot>extends true?Index:_IndexOfArray<Rest,Pivot,Increment<Index>>:-1;type _IndexOfString<T extends string,Pivot,Index extends number=0>=T extends`${infer First}${infer Rest extends string}`?IsEqual<First,Pivot>extends true?Index:_IndexOfString<Rest,Pivot,Increment<Index>>:-1;
1950
- /** -------------------------------------------------------
1951
- * * ***Utility Type: `IndexOf`.***
1952
- * --------------------------------------------------------
1953
- * **Type version of `Array.prototype.indexOf()` and `String.prototype.indexOf()`.**
1954
- * - Returns the index of the second argument in the first argument.
1955
- * @example
1956
- * ```ts
1957
- * type Case1 = IndexOf<[1, 2, 3], 2>; // ➔ 1
1958
- * type Case2 = IndexOf<[1, 2, 3], 4>; // ➔ -1
1959
- * type Case3 = IndexOf<'123', '2'>; // ➔ 1
1960
- * type Case4 = IndexOf<'123', '4'>; // ➔ -1
1961
- * ```
1962
- */
1963
- type IndexOf<T extends readonly unknown[]|string,Pivot extends T extends string?string:unknown>=T extends string?IsStringLiteral<T>extends true?_IndexOfString<T,Pivot>:never:T extends readonly unknown[]?IsTuple<T>extends true?_IndexOfArray<T,Pivot>:never:never;
1964
- /** -------------------------------------------------------
1965
- * * ***Utility Type: `IsArrayIndex`.***
1966
- * -------------------------------------------------------
1967
- * **Returns a boolean whether the passed argument is a valid array index.**
1968
- * @example
1969
- * ```ts
1970
- * type Case1 = IsArrayIndex<1>; // ➔ true
1971
- * type Case2 = IsArrayIndex<'1'>; // ➔ true
1972
- * type Case3 = IsArrayIndex<-1>; // ➔ false
1973
- * type Case4 = IsArrayIndex<"a">; // ➔ false
1974
- * ```
1975
- */
1976
- type IsArrayIndex<T>=T extends number?And<IsInteger<T>,IsGreaterOrEqual<T,0>>:T extends string?ParseNumber<T>extends infer NumT extends number?Not<IsNever<NumT>>extends true?And<IsInteger<NumT>,IsGreaterOrEqual<NumT,0>>:false:false:never;
1977
- /** -------------------------------------------------------
1978
- * * ***Utility Type: `Mod`.***
1979
- * -------------------------------------------------------
1980
- * **Returns the **remainder** of the division of two numbers (`Dividend % Divisor`).**
1981
- * - **Behavior:**
1982
- * - Computes the remainder using type-level arithmetic:
1983
- * - `Dividend - (Divisor * (Dividend / Divisor))`.
1984
- * - Works with integers within the range:
1985
- * - `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
1986
- * @template Dividend - The dividend (numerator).
1987
- * @template Divisor - The divisor (denominator).
1988
- * @example
1989
- * ```ts
1990
- * type T0 = Mod<1, 2>; // ➔ 1
1991
- * type T1 = Mod<1, 3>; // ➔ 1
1992
- * type T2 = Mod<10, 3>; // ➔ 1
1993
- * type T3 = Mod<7, 7>; // ➔ 0
1994
- * ```
1995
- */
1996
- type Mod<Dividend extends number,Divisor extends number>=Div<Dividend,Divisor>extends infer Quotient extends number?Multi<Quotient,Divisor>extends infer Product extends number?Sub<Dividend,Product>:never:never;
1997
- /** -------------------------------------------------------
1998
- * * ***Utility Type: `IsDivisibleByTwo`.***
1999
- * -------------------------------------------------------
2000
- * **Accepts an integer argument and returns a boolean whether it is divisible by two.**
2001
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2002
- * @example
2003
- * // truthy
2004
- * type Case1 = IsDivisibleByTwo<4>; // ➔ true
2005
- * type Case2 = IsDivisibleByTwo<-6>; // ➔ true
2006
- *
2007
- * // falsy
2008
- * type Case3 = IsDivisibleByTwo<3>; // ➔ false
2009
- * type Case4 = IsDivisibleByTwo<-5>; // ➔ false
2010
- */
2011
- type IsDivisibleByTwo<T extends number>=IsEven<T>;type DivisibleByThreeMap={3:true;6:true;9:true;};type _IsDivisibleByThree<T extends number>=DigitsTuple<Abs<T>>["digits"] extends infer Digits extends readonly number[]?IsEqual<Digits["length"],1>extends true?Digits[0] extends keyof DivisibleByThreeMap?true:false:SumArr<Digits>extends infer DigitsSum extends number?IfLowerThan<DigitsSum,3>extends true?false:_IsDivisibleByThree<DigitsSum>:never:never;
2012
- /** -------------------------------------------------------
2013
- * * ***Utility Type: `IsDivisibleByThree`.***
2014
- * -------------------------------------------------------
2015
- * **Accepts an integer argument and returns a boolean whether it is divisible by three.**
2016
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2017
- * @example
2018
- * // truthy
2019
- * type Case1 = IsDivisibleByThree<123>; // ➔ true
2020
- * type Case2 = IsDivisibleByThree<-126>; // ➔ true
2021
- *
2022
- * // falsy
2023
- * type Case3 = IsDivisibleByThree<124>; // ➔ false
2024
- * type Case4 = IsDivisibleByThree<-128>; // ➔ false
2025
- */
2026
- type IsDivisibleByThree<T extends number>=_IsDivisibleByThree<T>;
2027
- /** -------------------------------------------------------
2028
- * * ***Utility Type: `IsDivisibleByFive`.***
2029
- * -------------------------------------------------------
2030
- * **Accepts an integer argument and returns a boolean whether it is divisible by five.**
2031
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2032
- * @example
2033
- * // truthy
2034
- * type Case1 = IsDivisibleByFive<125>; // ➔ true
2035
- * type Case2 = IsDivisibleByFive<-115>; // ➔ true
2036
- *
2037
- * // falsy
2038
- * type Case3 = IsDivisibleByFive<13>; // ➔ false
2039
- * type Case4 = IsDivisibleByFive<-17>; // ➔ false
2040
- */
2041
- type IsDivisibleByFive<T extends number>=EndsWith<Stringify<T>,"0"|"5">;
2042
- /** -------------------------------------------------------
2043
- * * ***Utility Type: `IsDivisibleBySix`.***
2044
- * -------------------------------------------------------
2045
- * **Accepts an integer argument and returns a boolean whether it is divisible by six.**
2046
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2047
- * @example
2048
- * // truthy
2049
- * type Case1 = IsDivisibleBySix<126>; // ➔ true
2050
- * type Case2 = IsDivisibleBySix<-156>; // ➔ true
2051
- *
2052
- * // falsy
2053
- * type Case3 = IsDivisibleBySix<124>; // ➔ false
2054
- * type Case4 = IsDivisibleBySix<-139>; // ➔ false
2055
- */
2056
- type IsDivisibleBySix<T extends number>=And<IsDivisibleByTwo<T>,IsDivisibleByThree<T>>;
2057
- /** -------------------------------------------------------
2058
- * * ***Utility Type: `IsDivisibleByTen`.***
2059
- * -------------------------------------------------------
2060
- * **Accepts an integer argument and returns a boolean whether it is divisible by ten.**
2061
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2062
- * @example
2063
- * // truthy
2064
- * type Case1 = IsDivisibleByTen<100>; // ➔ true
2065
- * type Case2 = IsDivisibleByTen<-80>; // ➔ true
2066
- *
2067
- * // falsy
2068
- * type Case3 = IsDivisibleByTen<101>; // ➔ false
2069
- * type Case4 = IsDivisibleByTen<-72>; // ➔ false
2070
- */
2071
- type IsDivisibleByTen<T extends number>=EndsWith<Stringify<T>,"0">;
2072
- /** -------------------------------------------------------
2073
- * * ***Utility Type: `IsDivisibleByHundred`.***
2074
- * -------------------------------------------------------
2075
- * **Accepts an integer argument and returns a boolean whether it is divisible by hundred.**
2076
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2077
- * @example
2078
- * // truthy
2079
- * type Case1 = IsDivisibleByHundred<100>; // ➔ true
2080
- * type Case2 = IsDivisibleByHundred<-300>; // ➔ true
2081
- *
2082
- * // falsy
2083
- * type Case3 = IsDivisibleByHundred<101>; // ➔ false
2084
- * type Case4 = IsDivisibleByHundred<-210>; // ➔ false
2085
- */
2086
- type IsDivisibleByHundred<T extends number>=EndsWith<Stringify<T>,"00">;
2087
- /** -------------------------------------------------------
2088
- * * ***Utility Type: `IsDivisible`.***
2089
- * -------------------------------------------------------
2090
- * **Returns a boolean whether the first integer argument is divisible by the
2091
- * second integer argument.**
2092
- * @example
2093
- * // truthy
2094
- * type Case1 = IsDivisible<1024, 2>; // ➔ true
2095
- * type Case2 = IsDivisible<2034, 3>; // ➔ true
2096
- *
2097
- * // falsy
2098
- * type Case3 = IsDivisible<1023, 2>; // ➔ false
2099
- * type Case4 = IsDivisible<3034, 3>; // ➔ false
2100
- */
2101
- type IsDivisible<Dividend extends number,Divisor extends number>=IsEqual<Mod<Dividend,Divisor>,0>;
2102
- /** -------------------------------------------------------
2103
- * * ***Utility Type: `IsLetter`.***
2104
- * -------------------------------------------------------
2105
- * **Returns a boolean whether the passed argument is a letter (Only for letters that have both upper and lower case).**
2106
- * @template T - The string to check.
2107
- * @example
2108
- * type Case1 = IsLetter<'a'>; // ➔ true
2109
- * type Case2 = IsLetter<'1'>; // ➔ false
2110
- */
2111
- type IsLetter<T extends string>=Uppercase<T>extends Lowercase<T>?false:true;type _IsUnion<T,U=T>=IsNever<T>extends true?false:T extends U?Not<IsNever<Exclude<U,T>>>:false;
2112
- /** -------------------------------------------------------
2113
- * * ***Utility Type: `IsUnion`.***
2114
- * -------------------------------------------------------
2115
- * **Returns a boolean whether the passed argument is a union.**
2116
- * @template T - The type to check.
2117
- * @example
2118
- * type Case1 = IsUnion<'a' | 'b'>;
2119
- * // ➔ true
2120
- * type Case2 = IsUnion<'a'>;
2121
- * // ➔ false
2122
- */
2123
- type IsUnion<T>=_IsUnion<T,T>;
2124
- /** -------------------------------------------------------
2125
- * * ***Utility Type: `Join`.***
2126
- * -------------------------------------------------------
2127
- * **Type version of `Array.prototype.join()`.**
2128
- * - Joins the first array argument by the second argument.
2129
- * @template T - The array to join.
2130
- * @template Glue - The string or number to join with, defaultValue: `""`.
2131
- * @example
2132
- * type Case0 = Join<["p", "e", "a", "r"]>;
2133
- * // ➔ 'pear'
2134
- * type Case1 = Join<["a", "p", "p", "l", "e"], "-">;
2135
- * // ➔ 'a-p-p-l-e'
2136
- * type Case2 = Join<["2", "2", "2"], 1>;
2137
- * // ➔ '21212'
2138
- * type Case3 = Join<["o"], "u">;
2139
- * // ➔ 'o'
2140
- * type Case3 = Join<[], "n">;
2141
- * // ➔ never
2142
- */
2143
- type Join<T extends readonly(string|number)[],Glue extends string|number="">=IsTuple<T>extends true?T extends readonly [ infer First extends string|number,...infer Rest extends readonly(string|number)[]]?IfEmptyArray<Rest,First,`${First}${Glue}${Join<Rest, Glue>}`>:never:never;
2144
- /** --------------------------------------------------
2145
- * * ***Utility Type: `AnyRecord`.***
2146
- * --------------------------------------------------
2147
- * **Represents an object with arbitrary string keys and values of **any** type.**
2148
- * - ⚠️ **Use with caution — `any`** disables type safety.
2149
- * - Prefer stricter like {@link UnknownRecord | **`UnknownRecord`**} typing when possible.
2150
- * - ✅ Commonly used as a fallback for flexible key-value structures
2151
- * such as query parameters, configuration maps, or JSON-like data.
2152
- * @example
2153
- * ```ts
2154
- * const config: AnyRecord = {
2155
- * mode: "dark",
2156
- * retries: 3,
2157
- * debug: true,
2158
- * };
2159
- * ```
2160
- */
2161
- type AnyRecord=Record<string,any>;
2162
- /** --------------------------------------------------
2163
- * * ***Utility Type: `UnknownRecord`.***
2164
- * --------------------------------------------------
2165
- * **Represents an object with arbitrary string keys and values of **unknown** type.**
2166
- * - ✅ Safer alternative to `AnyRecord` — forces explicit type narrowing
2167
- * before values can be used, maintaining type safety.
2168
- * - ✅ Suitable for working with untyped external data sources
2169
- * (e.g., JSON APIs, parsed configs) where values must be validated first.
2170
- * @example
2171
- * ```ts
2172
- * const data: UnknownRecord = JSON.parse("{}");
2173
- *
2174
- * // Must narrow the type before usage
2175
- * if (typeof data.id === "string") {
2176
- * console.log(data.id.toUpperCase());
2177
- * }
2178
- *
2179
- * // Or:
2180
- * const unknownObject: UnknownRecord = {
2181
- * mode: "dark",
2182
- * retries: 3,
2183
- * debug: true,
2184
- * };
2185
- * ```
2186
- */
2187
- type UnknownRecord=Record<string,unknown>;
2188
- /** -------------------------------------------------------
2189
- * * ***Utility Type: `AnyStringRecord`.***
2190
- * -------------------------------------------------------
2191
- * **Same as **{@link AnyString | **`AnyString`**}** but uses `Record<never, never>` as the intersection.**
2192
- * - This approach is often more reliable in preserving literal types
2193
- * in generic inference scenarios.
2194
- * @example
2195
- * ```ts
2196
- * declare function acceptsAnyStringRecord<T extends AnyStringRecord>(value: T): T;
2197
- *
2198
- * const a = acceptsAnyStringRecord("hello");
2199
- * // ➔ "hello"
2200
- *
2201
- * const b = acceptsAnyStringRecord(String("world"));
2202
- * // ➔ string
2203
- * ```
2204
- */
2205
- type AnyStringRecord=Record<never,never>& string;
2206
- /** -------------------------------------------------------
2207
- * * ***Utility Type: `LooseLiteral`.***
2208
- * -------------------------------------------------------
2209
- * **Improves the autocompletion and inference of **loose literal types**.**
2210
- * @description
2211
- * Ensures that specified literal types are preserved while still
2212
- * allowing assignment of a broader base type.
2213
- * - **Useful in scenarios where:**
2214
- * - You want to accept **specific literal values** but still allow
2215
- * any value of a base type (like `string` or `number`).
2216
- * - You want stricter typing in generics while preserving literals.
2217
- * @template Literal - The literal type(s) to preserve.
2218
- * @template BaseType - The base type to extend when not matching literal.
2219
- * @example
2220
- * ```ts
2221
- * type T0 = LooseLiteral<"a" | "b" | "c", string>;
2222
- * // ➔ "a" | "b" | "c" | (string & {})
2223
- *
2224
- * declare function acceptsLoose<T extends LooseLiteral<"x" | "y", string>>(value: T): T;
2225
- * const a = acceptsLoose("x");
2226
- * // ➔ "x"
2227
- * const b = acceptsLoose("any string");
2228
- * // ➔ string
2229
- * ```
2230
- */
2231
- type LooseLiteral<Literal,BaseType>=Literal|(BaseType & AnyStringRecord);
2232
- /** -------------------------------------------------------
2233
- * * ***Utility Type: `Max`.***
2234
- * -------------------------------------------------------
2235
- * **Accepts two integers and returns the **maximum** among them.**
2236
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2237
- * @template Num1 - First integer to compare.
2238
- * @template Num2 - Second integer to compare.
2239
- * @example
2240
- * ```ts
2241
- * type Case1 = Max<1, 10>; // ➔ 10
2242
- * type Case2 = Max<1, -10>; // ➔ 1
2243
- * ```
2244
- */
2245
- type Max<Num1 extends number,Num2 extends number>=IfLowerThan<Num1,Num2,Num2,Num1>;
2246
- /** * ***Recursively computes the maximum number in a tuple of integers.***
2247
- *
2248
- * @private ***Private internal type for {@link MaxArr | **`MaxArr`**}.***
2249
- * @template T - Tuple of numbers to process.
2250
- * @template CurrentMax - Current maximum value, defaults to the first element of T.
2251
- */
2252
- type _MaxArr<T extends readonly number[],CurrentMax extends number=ReturnItselfIfNotExtends<T[0],undefined,never>>=IsEmptyArray<T>extends true?CurrentMax:Shift<T,{includeRemoved:true;}>extends [ infer Rest extends number[],infer First extends number]?_MaxArr<Rest,Max<First,CurrentMax>>:never;
2253
- /** -------------------------------------------------------
2254
- * * ***Utility Type: `MaxArr`.***
2255
- * -------------------------------------------------------
2256
- * **Accepts a tuple of integers and returns the **maximum** among its elements.**
2257
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2258
- * @template T - Tuple of numbers to evaluate.
2259
- * - Only tuples are supported; arrays of unknown length will return `never`.
2260
- * @example
2261
- * ```ts
2262
- * type Case1 = MaxArr<[1, 2, 4, 10]>; // ➔ 10
2263
- * type Case2 = MaxArr<[-1, 4, -10]>; // ➔ 4
2264
- * type Case3 = MaxArr<number[]>; // ➔ never (not a tuple)
2265
- * ```
2266
- */
2267
- type MaxArr<T extends readonly number[]>=IsTuple<T>extends true?_MaxArr<T>:never;
2268
- /** -------------------------------------------------------
2269
- * * ***Utility Type: `DeepMergeArrayUnion`.***
2270
- * -------------------------------------------------------
2271
- * **Recursively merges element types of nested arrays inside an array type,
2272
- * **preserving the nested array structure**.**
2273
- * - Converts an array of nested arrays into a union of its element types,
2274
- * while keeping the nested arrays intact.
2275
- * @template T - The outer array type.
2276
- * @returns The nested array type with merged element types.
2277
- * @example
2278
- * ```ts
2279
- * const test = [
2280
- * ["a", null],
2281
- * ["b", [undefined, "c"]],
2282
- * ];
2283
- *
2284
- * type Merged = DeepMergeArrayUnion<typeof test>;
2285
- * // ➔ ((string | null | (string | undefined)[])[])[]
2286
- * ```
2287
- */
2288
- type DeepMergeArrayUnion<T extends any[]>=T extends(infer U)[]?U extends any[]?DeepMergeArrayUnionHelper<U>[]:U[]:never;type DeepMergeArrayUnionHelper<T>=T extends(infer U)[]?DeepMergeArrayUnionHelper<U>|Exclude<T,any[]>:T;
2289
- /** -------------------------------------------------------
2290
- * * ***Utility Type: `Min`.***
2291
- * -------------------------------------------------------
2292
- * **Accepts two integers and returns the **minimum** among them.**
2293
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2294
- * @template Num1 - First integer.
2295
- * @template Num2 - Second integer.
2296
- * @example
2297
- * ```ts
2298
- * type Case1 = Min<1, 10>; // ➔ 1
2299
- * type Case2 = Min<1, -10>; // ➔ -10
2300
- * ```
2301
- */
2302
- type Min<Num1 extends number,Num2 extends number>=IfLowerThan<Num1,Num2,Num1,Num2>;
2303
- /** * ***Helper type for computing the minimum of a tuple of numbers recursively.***
2304
- *
2305
- * @private ***Private internal type for {@link MinArr | **`MinArr`**}.***
2306
- * @template T - Array of numbers
2307
- * @template CurrentMin - Current minimum in recursion
2308
- */
2309
- type _MinArr<T extends readonly number[],CurrentMin extends number=ReturnItselfIfNotExtends<T[0],undefined,never>>=IsEmptyArray<T>extends true?CurrentMin:Shift<T,{includeRemoved:true;}>extends [ infer Rest extends number[],infer First extends number]?_MinArr<Rest,Min<First,CurrentMin>>:never;
2310
- /** -------------------------------------------------------
2311
- * * ***Utility Type: `MinArr`.***
2312
- * -------------------------------------------------------
2313
- * **Accepts an array of integers and returns the **minimum** among its elements.**
2314
- * - Range: `[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]`.
2315
- * @template T - Tuple of numbers.
2316
- * @example
2317
- * ```ts
2318
- * type Case1 = MinArr<[1, 2, 4, 10]>; // ➔ 1
2319
- * type Case2 = MinArr<[-1, 4, -10]>; // ➔ -10
2320
- * ```
2321
- */
2322
- type MinArr<T extends readonly number[]>=IsTuple<T>extends true?_MinArr<T>:never;
2323
- /** -------------------------------------------------------
2324
- * * ***Utility Type: `NonNullableObject`.***
2325
- * -------------------------------------------------------
2326
- * **Makes all properties of the object type `T` non-nullable.**
2327
- * @template T - Object type to transform.
2328
- * @example
2329
- * ```ts
2330
- * type A = NonNullableObject<{ a: string | null; b: number | undefined }>;
2331
- * // ➔ { a: string; b: number }
2332
- * ```
2333
- */
2334
- type NonNullableObject<T>={[K in keyof T]:NonNullable<T[K]>;};
2335
- /** -------------------------------------------------------
2336
- * * ***Utility Type: `NonNullableObjectOnly`.***
2337
- * -------------------------------------------------------
2338
- * **Makes only the specified properties `K` of the object type `T` non-nullable.**
2339
- * @template T - Object type to transform.
2340
- * @template K - Keys of `T` to make non-nullable.
2341
- * @example
2342
- * ```ts
2343
- * type A = NonNullableObjectOnly<
2344
- * { a: string | null; b: number | undefined; c: boolean | null },
2345
- * "a" | "b"
2346
- * >;
2347
- * // ➔ { a: string; b: number; c: boolean | null }
2348
- * ```
2349
- */
2350
- type NonNullableObjectOnly<T,K extends keyof T>=Prettify<Pick<T,Exclude<keyof T,K>>&{[P in K]:NonNullable<T[P]>;}>;
2351
- /** -------------------------------------------------------
2352
- * * ***Utility Type: `NonNullableObjectExcept`.***
2353
- * -------------------------------------------------------
2354
- * **Makes all properties of the object type `T` non-nullable except for the specified properties `K`.**
2355
- * @template T - Object type to transform.
2356
- * @template K - Keys of `T` to leave unchanged.
2357
- * @example
2358
- * ```ts
2359
- * type A = NonNullableObjectExcept<
2360
- * { a: string | null; b: number | undefined; c: boolean | null },
2361
- * "c"
2362
- * >;
2363
- * // ➔ { a: string; b: number; c: boolean | null }
2364
- * ```
2365
- */
2366
- type NonNullableObjectExcept<T,K extends keyof T>=Prettify<Pick<T,K>&{[P in Exclude<keyof T,K>]:NonNullable<T[P]>;}>;
2367
- /** --------------------------------------------------
2368
- * * ***Internal Utility Type for: {@link NumberRangeLimit | `NumberRangeLimit`}.***
2369
- * --------------------------------------------------
2370
- * @template From - Starting number of the range (inclusive).
2371
- * @template To - Ending number of the range (inclusive).
2372
- * @template Result - Internal accumulator for recursion (do not set manually).
2373
- */
2374
- type _NumberRangeLimit<From extends number,To extends number,Result extends number[]=[From]>=IsGreaterThan<From,To>extends true?[...Result,To][number] extends infer R extends number?R extends R?IsGreaterThan<R,To>extends true?never:R:never:never:_NumberRangeLimit<Sum<From,7>,To,[ ...Result,From,Sum<From,1>,Sum<From,2>,Sum<From,3>,Sum<From,4>,Sum<From,5>,Sum<From,6>]>;
2375
- /** --------------------------------------------------
2376
- * * ***Utility Type: `NumberRangeLimit`.***
2377
- * --------------------------------------------------
2378
- * **Generate a union type of numbers within a specified range (optimized recursive batching).**
2379
- * @description
2380
- * Produces a **numeric union type** from `From` to `To` (inclusive),
2381
- * using ***batched recursive expansion*** (**adds up to `7` numbers at a time**).
2382
- *
2383
- * This batching allows generating **larger ranges** (`≥ 101`) efficiently without
2384
- * hitting TypeScript’s recursion limits too quickly.
2385
- * - ✅ Optimized for **performance** (fewer recursive steps).
2386
- * - ⚠️ Supports up to `To = 999` safely.
2387
- * - ⚙️ Best used for **larger ranges** (`≥ 101`) or when you need **arbitrary ranges** within `0–999`.
2388
- * - ℹ️ For **smaller ranges** (`≤ 100`) or when readability matters use {@link NumberRangeUnion | **`NumberRangeUnion`**} instead.
2389
- * @template From - Starting number of the range (inclusive).
2390
- * @template To - Ending number of the range (inclusive).
2391
- * @example
2392
- * ```ts
2393
- * type RangeA = NumberRangeLimit<5, 8>;
2394
- * // ➔ 5 | 6 | 7 | 8
2395
- * type RangeB = NumberRangeLimit<10, 15>;
2396
- * // ➔ 10 | 11 | 12 | 13 | 14 | 15
2397
- * type RangeC = NumberRangeLimit<8, 8>;
2398
- * // ➔ 8
2399
- * type RangeD = NumberRangeLimit<20, 10>;
2400
- * // ➔ 10
2401
- * ```
2402
- */
2403
- type NumberRangeLimit<From extends number,To extends number>=_NumberRangeLimit<From,To>;type _IsPalindrome<T extends string>=IsEmptyString<T>extends true?true:Not<IsStringLiteral<T>>extends true?false:T extends`${infer First extends string}${infer Rest extends string}`?IsEmptyString<Rest>extends true?true:Rest extends`${infer NewRest extends string}${First}`?_IsPalindrome<NewRest>:false:false;
2404
- /** -------------------------------------------------------
2405
- * * ***Utility Type: `IsPalindrome`.***
2406
- * -------------------------------------------------------
2407
- * **Determines if a string or number is a **palindrome** at type-level.
2408
- * A palindrome reads the same forwards and backwards (e.g., `"racecar"`).**
2409
- * @template T - A string or number to check.
2410
- * @example
2411
- * ```ts
2412
- * type T0 = IsPalindrome<"racecar">; // true
2413
- * type T1 = IsPalindrome<"hello">; // false
2414
- * type T2 = IsPalindrome<12321>; // true
2415
- * type T3 = IsPalindrome<12345>; // false
2416
- * ```
2417
- * @remarks
2418
- * - Converts numbers to strings using {@link Stringify | **`Stringify`**}.
2419
- * - Uses {@link IsEmptyString | **`IsEmptyString`**},
2420
- * {@link IsStringLiteral | **`IsStringLiteral`**},
2421
- * and {@link Not | **`Not`**} for type-level logic.
2422
- * - Returns `true` if the input is a palindrome, otherwise `false`.
2423
- */
2424
- type IsPalindrome<T extends string|number>=_IsPalindrome<Stringify<T>>;
2425
- /** -------------------------------------------------------
2426
- * * ***Utility Type: `UnionToIntersection`.***
2427
- * -------------------------------------------------------
2428
- * **Converts a union type into an **intersection**.**
2429
- * @description
2430
- * 📖 Reference: ***[`StackOverflow`](https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type/50375286#50375286).***
2431
- * @template U - The union type to be converted.
2432
- * @example
2433
- * ```ts
2434
- * type A = UnionToIntersection<{ a: string } | { b: number }>;
2435
- * // ➔ { a: string } & { b: number }
2436
- * type B = UnionToIntersection<
2437
- * { a: string } | { b: number } | { c: boolean }
2438
- * >;
2439
- * // ➔ { a: string } & { b: number } & { c: boolean }
2440
- * ```
2441
- */
2442
- type UnionToIntersection<U>=(U extends any?(k:U)=>void:never)extends(k:infer I)=>void?I:never;
2443
- /** -------------------------------------------------------
2444
- * * ***Utility Type: `PrettifyUnionIntersection`.***
2445
- * -------------------------------------------------------
2446
- * **Converts a union type into an **intersection** using ***{@link UnionToIntersection | `UnionToIntersection`}***, and then
2447
- * applies ***{@link Prettify | `Prettify`}*** to simplify the resulting intersection
2448
- * for better readability in IntelliSense and tooltips.**
2449
- * @description
2450
- * Useful when the raw intersection of union types produces
2451
- * deeply nested or hard-to-read structures.
2452
- * @template T - The union type to be converted.
2453
- * @template Options - Optional formatting options for `Prettify`.
2454
- * @example
2455
- * ```ts
2456
- * // Basic union ➔ intersection
2457
- * type A = { a: string } | { b: number };
2458
- * type B = PrettifyUnionIntersection<A>;
2459
- * // ➔ { a: string } & { b: number }
2460
- * // final result become ➔ { a: string b: number }
2461
- *
2462
- * // Larger union
2463
- * type C = { a: string } | { b: number } | { c: boolean };
2464
- * type D = PrettifyUnionIntersection<C>;
2465
- * // ➔ { a: string } & { b: number } & { c: boolean }
2466
- * // final result become ➔ { a: string b: number c: boolean }
2467
- *
2468
- * // With PrettifyOptions (custom formatting)
2469
- * type E = PrettifyUnionIntersection<A, { recursive: true }>;
2470
- * ```
2471
- */
2472
- type PrettifyUnionIntersection<T,Options extends PrettifyOptions=DefaultPrettifyOptions>=Prettify<UnionToIntersection<T>,Options>;
2473
- /** Internal Helper */
2474
-
2475
- /** Get optional keys of an object */
2476
- type OptionalKeys<T>={[P in keyof T]-?:{}extends Pick<T,P>?P:never;}[keyof T];
2477
- /** Get required keys of an object */
2478
- type RequiredKeys<T>=Exclude<keyof T,OptionalKeys<T>>;
2479
- /** Remove duplicate `undefined` from unions */
2480
- type CleanOptional$1<T>=[T] extends [undefined]?undefined:undefined extends T?Exclude<T,undefined>|undefined:T;
2481
- /** Required keys only (no optional ones) */
2482
- type RequiredKeysOf<U>=Exclude<keyof U,OptionalKeys<U>>;
2483
- /** Force re-evaluation / cleaner display */
2484
-
2485
- /** -------------------------------------------------------
2486
- * * ***Utility Type: `PartialOnly`.***
2487
- * -------------------------------------------------------
2488
- * **Make only the specified properties in `T` **optional**, while keeping all
2489
- * other properties required.**
2490
- * @template T - The object type to transform.
2491
- * @template K - Keys of `T` that should become optional.
2492
- * @example
2493
- * ```ts
2494
- * // Only "a" is optional, "b" and "c" remain required
2495
- * type T0 = PartialOnly<{ a: string; b: number; c: boolean }, "a">;
2496
- * // ➔ { a?: string; b: number; c: boolean }
2497
- *
2498
- * // Both "a" and "b" are optional
2499
- * type T1 = PartialOnly<{ a: string; b: number; c: boolean }, "a" | "b">;
2500
- * // ➔ { a?: string; b?: number; c: boolean }
2501
- *
2502
- * // Only "a" is optional (since "x" is not a valid key of T)
2503
- * type T2 = PartialOnly<{ a: string; b: number; c: boolean }, "a" | "x">;
2504
- * // ➔ { a?: string; b: number; c: boolean }
2505
- * ```
2506
- * - ℹ️ ***If key is never or not in object, all properties remain required:***
2507
- *
2508
- * ```ts
2509
- * type Skip1 = PartialOnly<{ a: string; b: number; c: boolean }, "x">;
2510
- * // ➔ { a: string; b: number; c: boolean }
2511
- *
2512
- * type Skip2 = PartialOnly<{ a: string; b: number; c: boolean }, never>;
2513
- * // ➔ { a: string; b: number; c: boolean }
2514
- * ```
2515
- */
2516
- type PartialOnly<T extends object,K extends keyof T|AnyString>=IsNever<K>extends true?T:PrettifyUnionIntersection<{[P in Exclude<RequiredKeys<T>,Extract<keyof T,K>>]-?:T[P];}&{[P in Exclude<OptionalKeys<T>,Extract<keyof T,K>>]+?:CleanOptional$1<T[P]>;}&{[P in Extract<keyof T,K>]+?:CleanOptional$1<T[P]>;}>;
2517
- /** -------------------------------------------------------
2518
- * * ***Utility Type: `PartialExcept`.***
2519
- * -------------------------------------------------------
2520
- * **Make all properties in `T` **optional**, except for the ones specified
2521
- * in `K`, which remain as-is.**
2522
- * - **Behavior:**
2523
- * - If a property in `K` is originally required ➔ it stays required.
2524
- * - If a property in `K` is originally optional ➔ it stays optional.
2525
- * - All other properties become optional.
2526
- * - Duplicate `undefined` types are cleaned up automatically.
2527
- * @template T - The object type to transform.
2528
- * @template K - Keys of `T` that should remain as-is (not forced optional).
2529
- * @example
2530
- * ```ts
2531
- * // "a" remains required, "b" and "c" become optional
2532
- * type T0 = PartialExcept<{ a: string; b: number; c: boolean }, "a">;
2533
- * // ➔ { a: string; b?: number; c?: boolean }
2534
- *
2535
- * // "a" and "b" remain required, "c" becomes optional
2536
- * type T1 = PartialExcept<{ a: string; b: number; c: boolean }, "a" | "b">;
2537
- * // ➔ { a: string; b: number; c?: boolean }
2538
- *
2539
- * // "b" is originally optional, so it stays optional,
2540
- * // "a" stays required, "c" becomes optional
2541
- * type T2 = PartialExcept<{ a: string; b?: number; c: boolean }, "a" | "b">;
2542
- * // ➔ { a: string; b?: number; c?: boolean }
2543
- *
2544
- * // none of the keys match ➔ everything optional
2545
- * type T3 = PartialExcept<{ a: string; b: number; c: boolean }, "x">;
2546
- * // ➔ { a?: string; b?: number; c?: boolean }
2547
- * ```
2548
- * - ℹ️ ***If key is never, all properties become optional:***
2549
- * ```ts
2550
- * type Skip = PartialExcept<{ a: string; b: number; c: boolean }, never>;
2551
- * // ➔ { a?: string; b?: number; c?: boolean }
2552
- * ```
2553
- */
2554
- type PartialExcept<T extends object,K extends keyof T|AnyString>=IsNever<K>extends true?Partial<T>:PrettifyUnionIntersection<Identity<{[P in RequiredKeysOf<Identity<Pick<T,Extract<keyof T,K>>&{[P in Exclude<keyof T,K>]?:T[P];}>>]-?:CleanOptional$1<Identity<Pick<T,Extract<keyof T,K>>&{[P in Exclude<keyof T,K>]?:T[P];}>[P]>;}&{[P in OptionalKeys<Identity<Pick<T,Extract<keyof T,K>>&{[P in Exclude<keyof T,K>]?:T[P];}>>]+?:CleanOptional$1<Identity<Pick<T,Extract<keyof T,K>>&{[P in Exclude<keyof T,K>]?:T[P];}>[P]>;}>>;
2555
- /** -------------------------------------------------------
2556
- * * ***Utility Type: `ValueOf`.***
2557
- * -------------------------------------------------------
2558
- * **Gets the types of all property values in an object `T`.**
2559
- * @template T - The object type.
2560
- * @example
2561
- * ```ts
2562
- * type Case1 = ValueOf<{ a: string, b: number }>;
2563
- * // ➔ string | number
2564
- * ```
2565
- */
2566
- type ValueOf<T>=T[keyof T];
2567
- /** -------------------------------------------------------
2568
- * * ***Utility Type: `ValueOfOnly`.***
2569
- * -------------------------------------------------------
2570
- * **Gets the types of properties in object `T` specified by `K`.**
2571
- * @template T - The object type.
2572
- * @template K - Keys of `T` to extract values from.
2573
- * @example
2574
- * ```ts
2575
- * type Case1 = ValueOfOnly<{ a: string, b: number }, "a">;
2576
- * // ➔ string
2577
- * ```
2578
- */
2579
- type ValueOfOnly<T,K extends keyof T>=T[K];
2580
- /** -------------------------------------------------------
2581
- * * ***Utility Type: `ValueOfExcept`.***
2582
- * -------------------------------------------------------
2583
- * **Gets the types of properties in object `T` **except** for keys in `K`.**
2584
- * @template T - The object type.
2585
- * @template K - Keys of `T` to exclude.
2586
- * @example
2587
- * ```ts
2588
- * type Case1 = ValueOfExcept<{ a: string, b: number }, "a">;
2589
- * // ➔ number
2590
- * ```
2591
- */
2592
- type ValueOfExcept<T,K extends keyof T>=T[keyof Omit<T,K>];
2593
- /** -------------------------------------------------------
2594
- * * ***Utility Type: `ValueOfArray`.***
2595
- * -------------------------------------------------------
2596
- * **Gets the types of elements in a tuple or array `T`.**
2597
- * @template T - The tuple or array type.
2598
- * @example
2599
- * ```ts
2600
- * type Case1 = ValueOfArray<[string, number]>;
2601
- * // ➔ string | number
2602
- * ```
2603
- */
2604
- type ValueOfArray<T extends readonly unknown[]>=T[number];
2605
- /** -------------------------------------------------------
2606
- * * ***Utility Type: `OverWritable`.***
2607
- * -------------------------------------------------------
2608
- * **Option type to signal that some properties can be overwritten when
2609
- * applying default options.**
2610
- * @property overwriteDefault - If true, all options in the passed `Options`
2611
- * object will **overwrite** defaults, even if rules say otherwise.
2612
- */
2613
- type OverWritable={
2614
- /** If true, all options in the passed `Options` object will **overwrite** defaults, even if rules say otherwise, defaultValue: `false`.
2615
- *
2616
- * @default false
2617
- */
2618
- overwriteDefault?:boolean;};
2619
- /** -------------------------------------------------------
2620
- * * ***Utility Type: `ApplyDefaultOptions`.***
2621
- * -------------------------------------------------------
2622
- * **Type-level utility that merges a user-specified `Options` object
2623
- * with a `DefaultOptions` object using a set of `OverwriteRules`.**
2624
- * @template BaseOptions - The base type of all options.
2625
- * @template Options - User-specified options that may override defaults.
2626
- * @template DefaultOptions - Default values for options.
2627
- * @template OverwriteRules - A mapping that indicates which keys
2628
- * should always allow overwriting defaults.
2629
- * @template OverwriteDefault - If true, all options in `Options`
2630
- * overwrite defaults regardless of rules.
2631
- * @remarks
2632
- * - Recursively applies defaults for nested objects.
2633
- * - Only objects that are non-nullable and non-unknown are recursively merged.
2634
- * - If a property is **not an object** or recursion is not needed,
2635
- * it either takes the value from `Options` or merges `Options[K] | DefaultOptions[K]`.
2636
- * - Helps safely build strongly typed configuration objects with defaults.
2637
- * @example
2638
- * ```ts
2639
- * type Base = {
2640
- * a: { x: number; y: string };
2641
- * b: boolean;
2642
- * };
2643
- *
2644
- * type Defaults = {
2645
- * a: { x: 1; y: "default" };
2646
- * b: true;
2647
- * };
2648
- *
2649
- * type UserOptions = {
2650
- * a: { y: "custom" };
2651
- * };
2652
- *
2653
- * type Result = ApplyDefaultOptions<Base, UserOptions, Defaults, { a: true; b: false }>;
2654
- * // Result: {
2655
- * // a: { x: 1; y: "custom"; tra: "test" };
2656
- * // b: boolean;
2657
- * // }
2658
- * ```
2659
- */
2660
- type ApplyDefaultOptions<BaseOptions,Options extends BaseOptions,DefaultOptions extends BaseOptions,OverwriteRules,OverwriteDefault extends boolean=false>=Prettify<{[K in keyof BaseOptions]-?:K extends keyof Options?AndArr<[ Extends<NonNullable<BaseOptions[K]>,object>,Not<IsNever<DefaultOptions[K]>>,Not<IsUnknown<BaseOptions[K]>>]>extends true?ApplyDefaultOptions<NonNullable<BaseOptions[K]>,Extract<Options[K],NonNullable<BaseOptions[K]>>,Extract<DefaultOptions[K],NonNullable<BaseOptions[K]>>,OverwriteRules[K & keyof OverwriteRules],OverwriteDefault>&{tra:"test";}:Or<IsEqual<OverwriteDefault,true>,And<Extends<K,keyof OverwriteRules>,Extends<OverwriteRules[K & keyof OverwriteRules],true>>>extends true?Options[K]:Options[K]|DefaultOptions[K]:DefaultOptions[K];}>;
2661
- /** --------------------------------------------------------------
2662
- * * ***Options for {@link PathToFields | **`PathToFields`**} type-level utility.***
2663
- * --------------------------------------------------------------
2664
- * @template ignoredTypes - Types to ignore completely.
2665
- * @template stopTypes - Types at which recursion stops and returns `[]`.
2666
- * @template limit - Max recursion depth.
2667
- * @template format - Output format, `"dot"` or `"array"`.
2668
- * @template ignoredKeys - Keys to ignore when generating paths.
2669
- * @template arrayIndexing - Options for handling array paths.
2670
- */
2671
- type PathToFieldsOptions=Prettify<OverWritable &{
2672
- /** Types to ignored completely (default: `undefined`).
2673
- *
2674
- * @default undefined
2675
- */
2676
- ignoredTypes?:unknown;
2677
- /** Types at which recursion stops (default: `undefined`).
2678
- *
2679
- * @default undefined
2680
- */
2681
- stopTypes?:unknown;
2682
- /** Max recursion depth (default: `10`).
2683
- *
2684
- * @default 10
2685
- */
2686
- limit?:number;
2687
- /** Format Output Options:
2688
- * - `"dot"` ➔ dot-notation strings, default output (`"a.b.c"`).
2689
- * - `"array"` ➔ array of path segments (`["a", "b", "c"]`).
2690
- *
2691
- * @default "dot"
2692
- */
2693
- format?:"dot"|"array";
2694
- /** Keys to skip when generating paths (default: `undefined`).
2695
- *
2696
- * @default undefined
2697
- */
2698
- ignoredKeys?:PropertyKey;
2699
- /** Options for array Indexing (default: `{ exactIndexes: false }`).
2700
- *
2701
- * When `arrayIndexing.exactIndexes = true` ➔ outputs exact tuple indexes (`"arr.0"`), otherwise generic `"arr.${number}"`.
2702
- * @default undefined
2703
- */
2704
- arrayIndexing?:{
2705
- /** Options for array Exact Indexing (default: `false`).
2706
- *
2707
- * When `exactIndexes = true` ➔ outputs exact tuple indexes (`"arr.0"`), otherwise generic `"arr.${number}"`.
2708
- * - For increase limit indexing, you can set `limit` options, default
2709
- * limit is: `10`.
2710
- * @default false
2711
- */
2712
- exactIndexes:boolean;};},{recursive:true;}>;
2713
- /** * ***Default options for {@link PathToFields}.*** */
2714
- type DefaultPathToFieldsOptions={ignoredTypes:never;stopTypes:string|number|boolean|symbol|Date|AnyFunction;format:"dot";limit:10;ignoredKeys:never;arrayIndexing:{exactIndexes:false;};};type OverwriteRules={limit:true;format:true;arrayIndexing:{exactIndexes:true;};};type Booleanize<T>=T extends true?true:false;type _PathToFieldsArray<T extends readonly unknown[],Options extends PathToFieldsOptions,Iteration extends number=0>=And<IsTuple<T>,IsEqual<Booleanize<Options["arrayIndexing"] extends{exactIndexes:infer E;}?E:false>,true>>extends true?ValueOfArray<{[K in keyof T]:IsArrayIndex<K>extends true?[K,..._PathToFields<T[K],Options,Increment<Iteration>>]:never;}>:ArrayElementType<T>extends infer ElementType?[`${number}`,...(ElementType extends ElementType?_PathToFields<ElementType,Options,Increment<Iteration>>:never)]:never;type _PathToFields<T,Options extends PathToFieldsOptions,Iteration extends number=0>=T extends Options["ignoredTypes"]?never:T extends Options["stopTypes"]?[]:IsEqual<Iteration,Options["limit"]>extends true?never:T extends readonly unknown[]?_PathToFieldsArray<T,Options,Iteration>:ValueOf<{[K in Exclude<keyof T,symbol|Options["ignoredKeys"]>]:NonNullable<T[K]>extends infer NonNullableFields?NonNullableFields extends readonly unknown[]?[K,..._PathToFieldsArray<NonNullableFields,Options,Iteration>]:[K,..._PathToFields<NonNullableFields,Options,Increment<Iteration>>]:never;}>;
2715
- /** -------------------------------------------------------
2716
- * * ***Utility Type: `PathToFields`.***
2717
- * -------------------------------------------------------
2718
- * **Generates **all possible property paths** within a type `T`.
2719
- * Supports nested objects, arrays, tuples, and optional configuration.**
2720
- * @template T - Object type to extract paths from.
2721
- * @template Options - Optional configuration.
2722
- * @example
2723
- * ```ts
2724
- * // Nested object
2725
- * type T1 = PathToFields<{ a: { b: { c: number } } }>;
2726
- * // Result: "a.b.c"
2727
- *
2728
- * // Array of objects (dot notation, default)
2729
- * type T2 = PathToFields<{ arr: { id: string; value: number }[] }>;
2730
- * // Result: "arr.${number}.id" | "arr.${number}.value"
2731
- *
2732
- * // Output format as array of path segments
2733
- * type T4 = PathToFields<
2734
- * { user: { profile: { name: string } } },
2735
- * { format: "array" }
2736
- * >;
2737
- * // Result: ["user", "profile", "name"]
2738
- *
2739
- * // Ignoring specific keys
2740
- * type T5 = PathToFields<
2741
- * { id: string; password: string; profile: { bio: string } },
2742
- * { ignoredKeys: "password" }
2743
- * >;
2744
- * // Result: "id" | "profile.bio"
2745
- *
2746
- * // Stopping recursion at specific types
2747
- * type T6 = PathToFields<
2748
- * { settings: Date; nested: { inner: number } },
2749
- * { stopTypes: Date }
2750
- * >;
2751
- * // Result: "settings" | "nested.inner"
2752
- * ```
2753
- * @remarks
2754
- * - `Options.format = "dot"` ➔ dot-notation strings, default output (`"a.b.c"`).
2755
- * - `Options.format = "array"` ➔ array of path segments (`["a", "b", "c"]`).
2756
- * - `Options.limit` ➔ max recursion depth (default 10).
2757
- * - `Options.stopTypes` ➔ types at which recursion stops.
2758
- * - `Options.ignoredTypes` ➔ types ignored completely.
2759
- * - `Options.ignoredKeys` ➔ keys to skip when generating paths.
2760
- * - `Options.arrayIndexing.exactIndexes = true` ➔ outputs exact tuple indexes (`"arr.0"`), otherwise generic `"arr.${number}"`.
2761
- */
2762
- type PathToFields<T,Options extends PathToFieldsOptions=never>=(IsNever<Options>extends true?DefaultPathToFieldsOptions:ApplyDefaultOptions<Omit<PathToFieldsOptions,keyof OverWritable>,Options,DefaultPathToFieldsOptions,OverwriteRules,PathToFieldsOptions["overwriteDefault"] extends boolean?PathToFieldsOptions["overwriteDefault"]:false>)extends infer MergedOptions extends PathToFieldsOptions?_PathToFields<T,MergedOptions>extends infer Paths extends readonly(string|number)[]?IsEqual<MergedOptions["format"],"dot">extends true?Paths extends Paths?Join<Paths,".">:never:Paths:never:never;type _Pow<Num extends number,Factor extends number,CurrentProduct extends number=1,Iteration extends unknown[]=[]>=IsEqual<Iteration["length"],Factor>extends true?CurrentProduct:_Pow<Num,Factor,Multi<CurrentProduct,Num>,Push<Iteration,unknown>>;
2763
- /** -------------------------------------------------------
2764
- * * ***Utility Type: `Pow`.***
2765
- * -------------------------------------------------------
2766
- * **Returns a type-level **exponentiation** result:**
2767
- * - Raises the first integer parameter (`Num`) to the power of the second
2768
- * integer parameter (`Factor`).
2769
- * @template Num - The base number (integer).
2770
- * @template Factor - The exponent number (integer, >= 0).
2771
- * @example
2772
- * ```ts
2773
- * type Case1 = Pow<10, 2>
2774
- * // ➔ 100
2775
- * type Case2 = Pow<5, 0>
2776
- * // ➔ 1
2777
- * type Case3 = Pow<2, 3>
2778
- * // ➔ 8
2779
- * ```
2780
- */
2781
- type Pow<Num extends number,Factor extends number>=_Pow<Num,Factor>;
2782
- /** -------------------------------------------------------
2783
- * * ***Utility Type: `ReadonlyOnly`.***
2784
- * -------------------------------------------------------
2785
- * **Makes the specified keys `K` of an object type `T` readonly,
2786
- * while leaving the other properties mutable.**
2787
- * @template T - The object type.
2788
- * @template K - Keys of `T` to make readonly.
2789
- * @example
2790
- * ```ts
2791
- * type T0 = ReadonlyOnly<{ a: string; b: number }, 'a'>;
2792
- * // ➔ { readonly a: string; b: number }
2793
- *
2794
- * type T1 = ReadonlyOnly<{ x: boolean; y: number; z: string }, 'y' | 'z'>;
2795
- * // ➔ { x: boolean; readonly y: number; readonly z: string }
2796
- * ```
2797
- */
2798
- type ReadonlyOnly<T extends object,K extends keyof T>=Prettify<Pick<T,Exclude<keyof T,K>>&{readonly [P in K]:T[P];}>;
2799
- /** -------------------------------------------------------
2800
- * * ***Utility Type: `ReadonlyExcept`.***
2801
- * -------------------------------------------------------
2802
- * **Makes all properties of an object type `T` readonly,
2803
- * except for the specified keys `K` which remain mutable.**
2804
- * @template T - The object type.
2805
- * @template K - Keys of `T` to remain mutable.
2806
- * @example
2807
- * ```ts
2808
- * type T0 = ReadonlyExcept<{ a: string; b: number }, 'a'>;
2809
- * // ➔ { a: string; readonly b: number }
2810
- *
2811
- * type T1 = ReadonlyExcept<{ x: boolean; y: number; z: string }, 'x' | 'z'>;
2812
- * // ➔ { x: boolean; readonly y: number; z: string }
2813
- * ```
2814
- */
2815
- type ReadonlyExcept<T extends object,K extends keyof T>=Prettify<Pick<T,K>&{readonly [P in Exclude<keyof T,K>]:T[P];}>;
2816
- /** -------------------------------------------------------
2817
- * * ***Utility Type: `RemoveIndexSignature`.***
2818
- * -------------------------------------------------------
2819
- * **Removes **index signatures** (e.g., `[key: string]: any`) from an object
2820
- * type `T`, leaving only explicitly declared properties.**
2821
- * @template T - The object type to process.
2822
- * @example
2823
- * ```ts
2824
- * type Case1 = RemoveIndexSignature<{ [key: string]: number | string; a: string }>;
2825
- * // ➔ { a: string }
2826
- *
2827
- * type Case2 = RemoveIndexSignature<{ x: number; y: boolean }>;
2828
- * // ➔ { x: number; y: boolean }
2829
- *
2830
- * type Case3 = RemoveIndexSignature<{ [key: string]: number }>;
2831
- * // ➔ {} // all keys were index signatures
2832
- * ```
2833
- */
2834
- type RemoveIndexSignature<T>={[Key in keyof T as Key extends`${infer _}`?Key:never]:T[Key];};
2835
- /** -------------------------------------------------------
2836
- * * ***Utility Type: `Replace`.***
2837
- * -------------------------------------------------------
2838
- * **Replaces the **first occurrence** of a substring (`Pivot`)
2839
- * inside a string (`T`) with another substring (`ReplaceBy`).**
2840
- * @template T - The source string.
2841
- * @template Pivot - The substring to replace.
2842
- * @template ReplaceBy - The substring that replaces `Pivot`.
2843
- * @example
2844
- * ```ts
2845
- * type Case1 = Replace<'remove me me', 'me', 'him'>;
2846
- * // ➔ 'remove him me'
2847
- * type Case2 = Replace<'remove me me', 'us', 'him'>;
2848
- * // ➔ 'remove me me'
2849
- * type Case3 = Replace<'aaaa', 'a', 'b'>;
2850
- * // ➔ 'baaa'
2851
- * type Case4 = Replace<'hello', 'x', 'y'>;
2852
- * // ➔ 'hello' (no match found)
2853
- * ```
2854
- */
2855
- type Replace<T extends string,Pivot extends string,ReplaceBy extends string>=T extends`${infer A}${Pivot}${infer B}`?`${A}${ReplaceBy}${B}`:T;
2856
- /** --------------------------------------------------
2857
- * * ***Utility Type: `ReplaceToPartial`.***
2858
- * --------------------------------------------------
2859
- * **Replaces specified keys in a type with a new value type, making them optional.**
2860
- * - ✅ Useful when certain properties in a type should allow partial overrides
2861
- * while keeping the rest of the structure intact.
2862
- * @template TypeToBeChecked - The original object type.
2863
- * @template KeyToBeReplaced - The keys in the original type to be replaced.
2864
- * @template NewValueToUse - The new type to assign to the replaced keys.
2865
- * @example
2866
- * ```ts
2867
- * type A = { name: string; age: number };
2868
- * type B = ReplaceToPartial<A, 'age', string>;
2869
- * // ➔ { name: string; age?: string }
2870
- * ```
2871
- */
2872
- type ReplaceToPartial<TypeToBeChecked,KeyToBeReplaced extends keyof TypeToBeChecked,NewValueToUse>=Identity<Pick<TypeToBeChecked,Exclude<keyof TypeToBeChecked,KeyToBeReplaced>>&{[P in KeyToBeReplaced]?:NewValueToUse;}>;
2873
- /** --------------------------------------------------
2874
- * * ***Utility Type: `ReplaceToRequired`.***
2875
- * --------------------------------------------------
2876
- * **Replaces specified keys in a type with a new value type, making them required.**
2877
- * - ✅ Useful when redefining a property’s type while ensuring it's required.
2878
- * @template TypeToBeChecked - The original object type.
2879
- * @template KeyToBeReplaced - The keys in the original type to be replaced.
2880
- * @template NewValueToUse - The new type to assign to the replaced keys.
2881
- * @example
2882
- * ```ts
2883
- * type A = { name?: string | string[]; age: number };
2884
- * type B = ReplaceToRequired<A, 'name', string>;
2885
- * // ➔ { name: string; age: number }
2886
- * ```
2887
- */
2888
- type ReplaceToRequired<TypeToBeChecked,KeyToBeReplaced extends keyof TypeToBeChecked,NewValueToUse>=Identity<Pick<TypeToBeChecked,Exclude<keyof TypeToBeChecked,KeyToBeReplaced>>&{[P in KeyToBeReplaced]:NewValueToUse;}>;
2889
- /** Internal Helper */
2890
-
2891
- /** Remove duplicate `undefined` from a type */
2892
- type CleanOptional<T>=[T] extends [undefined]?undefined:T;
2893
- /** -------------------------------------------------------
2894
- * * ***Utility Type: `RequiredOnly`.***
2895
- * -------------------------------------------------------
2896
- * **Make only the specified properties in `T` **required**, while keeping the rest unchanged (remain optional if optional).**
2897
- * @template T - The object type to transform.
2898
- * @template K - Keys of `T` that should become required.
2899
- * @example
2900
- * ```ts
2901
- * // Only "a" is required, "b" and "c" remain optional
2902
- * type T0 = RequiredOnly<{ a?: number; b?: string; c?: boolean }, "a">;
2903
- * // ➔ { a: number; b?: string; c?: boolean }
2904
- *
2905
- * // Both "a" and "b" are required
2906
- * type T1 = RequiredOnly<{ a?: number; b?: string; c?: boolean }, "a" | "b">;
2907
- * // ➔ { a: number; b: string; c?: boolean }
2908
- *
2909
- * // Only "a" is required (since "x" is not a valid key of T)
2910
- * type T2 = RequiredOnly<{ a?: number; b?: string; c?: boolean }, "a" | "x">;
2911
- * // ➔ { a: number; b?: string; c?: boolean }
2912
- * ```
2913
- * - ℹ️ ***If key is never or not in object, all properties remain unchanged:***
2914
- * ```ts
2915
- * type Skip1 = RequiredOnly<{ a?: number; b?: string; c?: boolean }, "x">;
2916
- * // ➔ { a?: number; b?: string; c?: boolean }
2917
- *
2918
- * type Skip2 = RequiredOnly<{ a?: number; b?: string; c?: boolean }, never>;
2919
- * // ➔ { a?: number; b?: string; c?: boolean }
2920
- * ```
2921
- */
2922
- type RequiredOnly<T extends object,K extends keyof T|AnyString>=IsNever<K>extends true?T:PrettifyUnionIntersection<{[P in Exclude<keyof T,K>]?:CleanOptional<T[P]>;}&{[P in Extract<keyof T,K>]-?:NonUndefined<CleanOptional<T[P]>>;}>;
2923
- /** -------------------------------------------------------
2924
- * * ***Utility Type: `RequiredExcept`.***
2925
- * -------------------------------------------------------
2926
- * **Make **all properties** in `T` required, except the specified keys which remain optional.**
2927
- * @template T - The object type to transform.
2928
- * @template K - Keys of `T` that should remain optional.
2929
- * @example
2930
- * ```ts
2931
- * // All required except "a"
2932
- * type T0 = RequiredExcept<{ a?: number; b?: string; c?: boolean }, "a">;
2933
- * // ➔ { a?: number; b: string; c: boolean }
2934
- *
2935
- * // All required except "a" and "b"
2936
- * type T1 = RequiredExcept<{ a?: number; b?: string; c?: boolean }, "a" | "b">;
2937
- * // ➔ { a?: number; b?: string; c: boolean }
2938
- *
2939
- * // Only "a" remains optional (since "x" is not a valid key of T)
2940
- * type T2 = RequiredExcept<{ a?: number; b?: string; c?: boolean }, "a" | "x">;
2941
- * // ➔ { a?: number; b: string; c: boolean }
2942
- * ```
2943
- *
2944
- * - ℹ️ ***If key is never or not in object, all properties become required:***
2945
- * ```ts
2946
- * type Skip1 = RequiredExcept<{ a?: number; b?: string; c?: boolean }, "x">;
2947
- * // ➔ { a: number; b: string; c: boolean }
2948
- *
2949
- * type Skip2 = RequiredExcept<{ a?: number; b?: string; c?: boolean }, never>;
2950
- * // ➔ { a: number; b: string; c: boolean }
2951
- * ```
2952
- */
2953
- type RequiredExcept<T extends object,K extends keyof T|AnyString>=IsNever<K>extends true?Required<T>:PrettifyUnionIntersection<{[P in Exclude<keyof T,K>]-?:NonUndefined<CleanOptional<T[P]>>;}&{[P in Extract<keyof T,K>]?:CleanOptional<T[P]>;}>;type _Reverse<T extends readonly unknown[],Result extends readonly unknown[]=[]>=T extends readonly [infer First,...infer Rest]?_Reverse<Rest,[First,...Result]>:Result;type FilterByType$1<T extends readonly unknown[],U>=T extends readonly [ infer Head,...infer Tail]?Head extends U?[Head,...FilterByType$1<Tail,U>]:FilterByType$1<Tail,U>:[];type Grouped<T extends readonly unknown[]>=[ ...FilterByType$1<T,number>,...FilterByType$1<T,string>,...FilterByType$1<T,boolean>,...FilterByType$1<T,Exclude<T[number],number|string|boolean>>];type MaybeReadonly<T extends readonly unknown[],R extends readonly unknown[]>=IsTuple<T>extends true?(IsReadonlyArray<T>extends true?Readonly<R>:R):R;
2954
- /** -------------------------------------------------------
2955
- * * ***Utility Type: `Reverse`.***
2956
- * -------------------------------------------------------
2957
- * **Returns a new tuple or readonly array type with the elements in reverse order.**
2958
- * - **Behavior:**
2959
- * 1. **Tuple**: The reversed result preserves tuple properties,
2960
- * including `readonly` if applicable.
2961
- * - Elements are **grouped in this order before reversing**:
2962
- * `number`, `string`, `boolean`, then any other types.
2963
- * 2. **Normal array (non-tuple)**: The type is returned as-is (no reversal).
2964
- * - ℹ️ **Notes:**
2965
- * - Supports arbitrary types in the tuple, including objects, Date, symbol, etc.
2966
- * - Grouping ensures that numbers, strings, and booleans are reversed in logical
2967
- * groups, while other types remain at the end in their original order before
2968
- * reverse.
2969
- * @template T - The array or tuple type to reverse.
2970
- * @example
2971
- * ```ts
2972
- * // Mutable tuple of numbers
2973
- * type T0 = Reverse<[1, 2, 3]>;
2974
- * // Grouped: [1,2,3] (numbers first)
2975
- * // Reversed: [3, 2, 1]
2976
- *
2977
- * // Readonly tuple of numbers
2978
- * type T1 = Reverse<readonly [1, 2, 3]>;
2979
- * // Grouped: [1,2,3]
2980
- * // Reversed: readonly [3, 2, 1]
2981
- *
2982
- * // Tuple of strings
2983
- * type T2 = Reverse<["a", "b", "c"]>;
2984
- * // Grouped: ["a","b","c"]
2985
- * // Reversed: ["c","b","a"]
2986
- *
2987
- * // Readonly tuple of strings
2988
- * type T3 = Reverse<readonly ["x", "y", "z"]>;
2989
- * // Grouped: ["x","y","z"]
2990
- * // Reversed: readonly ["z","y","x"]
2991
- *
2992
- * // Tuple of mixed types (numbers, strings, booleans)
2993
- * type T4 = Reverse<[1, "a", true, 2, "b", false]>;
2994
- * // Grouped: [1,2,"a","b",true,false]
2995
- * // Reversed: [false,"b","a",2,1,true]
2996
- *
2997
- * // Readonly tuple of mixed types
2998
- * type T5 = Reverse<readonly [false, "b", 2, "x", true]>;
2999
- * // Grouped: [2,"b","x",false,true]
3000
- * // Reversed: readonly [true,false,"x","b",2]
3001
- *
3002
- * // Tuple with arbitrary types (Date, object, symbol, bigint, etc.)
3003
- * type T6 = Reverse<[1, "a", true, 2, "b", false, Date, {x:1}, symbol, 10n]>;
3004
- * // Grouped: [1,2,"a","b",true,false,Date,{x:1},symbol,10n]
3005
- * // Reversed: [10n,symbol,{x:1},Date,false,true,"b","a",2,1]
3006
- *
3007
- * // Normal arrays (not tuples) remain unchanged
3008
- * type T7 = Reverse<number[]>;
3009
- * // ➔ number[]
3010
- *
3011
- * type T8 = Reverse<string[]>;
3012
- * // ➔ string[]
3013
- *
3014
- * type T9 = Reverse<(number | string)[]>;
3015
- * // ➔ (string | number)[]
3016
- *
3017
- * type T10 = Reverse<(boolean | number | string)[]>;
3018
- * // ➔ (string | number | boolean)[]
3019
- * ```
3020
- */
3021
- type Reverse<T extends readonly unknown[]>=T extends readonly [ unknown,...unknown[]]?_Reverse<Grouped<T>>extends infer R extends readonly unknown[]?MaybeReadonly<T,R>:never:T;
3022
- /** -------------------------------------------------------
3023
- * * ***Utility Type: `Round`.***
3024
- * -------------------------------------------------------
3025
- * **Type-level version of `Math.round()`.
3026
- * Returns the value of a number rounded to the **nearest integer**.**
3027
- * - **Behavior:**
3028
- * - If `T` is a float, it rounds to the nearest whole number:
3029
- * - Fraction `≥ 0.5` ➔ rounds up.
3030
- * - Fraction `< 0.5` ➔ rounds down.
3031
- * - If `T` is already an integer, it returns `T` as-is.
3032
- * @template T - The number type to round.
3033
- * @example
3034
- * ```ts
3035
- * // Positive float
3036
- * type T0 = Round<3.14>;
3037
- * // ➔ 3
3038
- *
3039
- * // Negative float
3040
- * type T1 = Round<-3.14>;
3041
- * // ➔ -3
3042
- *
3043
- * // Fraction ≥ 0.5
3044
- * type T2 = Round<2.6>;
3045
- * // ➔ 3
3046
- *
3047
- * // Already integer
3048
- * type T3 = Round<5>;
3049
- * // ➔ 5
3050
- * ```
3051
- */
3052
- type Round<T extends number>=IsFloat<T>extends true?GetFloatNumberParts<T>extends [ infer Whole extends number,infer Fraction extends number]?IsGreaterThan<FirstDigit<Fraction>,4>extends true?Increment<Whole>:Whole:never:T;type SliceRemovedItemValue=Record<"__type-rzl_internal__",symbol>;type FilterRemoved<T extends readonly unknown[],Result extends unknown[]=[]>=T extends readonly [infer First,...infer Rest extends unknown[]]?FilterRemoved<Rest,First extends SliceRemovedItemValue?Result:Push<Result,First>>:Result;
3053
- /** -------------------------------------------------------
3054
- * * ***Utility Type: `Slice`.***
3055
- * -------------------------------------------------------
3056
- * **Type-level version of `Array.prototype.slice()`.**
3057
- * @description
3058
- * Returns a shallow copy of a portion of an array, selected from `Start` to `End` (not including `End`).
3059
- * - **Behavior:**
3060
- * - `Start` defaults to `0`.
3061
- * - `End` defaults to `T["length"]`.
3062
- * - Negative indices are interpreted as `T["length"] + index`.
3063
- * - If `Start >= T["length"]` or `End <= Start`, returns an empty array `[]`.
3064
- * - If the full range is selected, returns `T` as-is.
3065
- * @template T - The array type to slice.
3066
- * @template Start - The start index (inclusive). Defaults to `0`.
3067
- * @template End - The end index (exclusive). Defaults to `T["length"]`.
3068
- * @example
3069
- * ```ts
3070
- * // Slice from index 1 to end
3071
- * type T0 = Slice<[1, 2, 3, 4], 1>;
3072
- * // ➔ [2, 3, 4]
3073
- *
3074
- * // Slice from index 1 to 3
3075
- * type T1 = Slice<[1, 2, 3, 4], 1, 3>;
3076
- * // ➔ [2, 3]
3077
- *
3078
- * // Slice with negative start
3079
- * type T2 = Slice<[1, 2, 3, 4], -2>;
3080
- * // ➔ [3, 4]
3081
- *
3082
- * // Slice with negative end
3083
- * type T3 = Slice<[1, 2, 3, 4], 1, -1>;
3084
- * // ➔ [2, 3]
3085
- *
3086
- * // Slice exceeding array length
3087
- * type T4 = Slice<[1, 2, 3], 0, 10>;
3088
- * // ➔ [1, 2, 3]
3089
- *
3090
- * // Slice resulting in empty array
3091
- * type T5 = Slice<[1, 2, 3], 3, 2>;
3092
- * // ➔ []
3093
- * ```
3094
- */
3095
- type Slice<T extends readonly unknown[],Start extends number=0,End extends number=T["length"]>=(IsEmptyArray<T>extends true?"self":IsGreaterOrEqual<Start,T["length"]>extends true?"empty":IsNegative<End>extends true?IsGreaterOrEqual<Abs<End>,T["length"]>extends true?"empty":[IfPositive<Start,Start,Sum<T["length"],Start>>,Sum<T["length"],End>]:And<Or<IsEqual<Start,0>,IsGreaterOrEqual<Abs<Start>,T["length"]>>,IsGreaterOrEqual<End,T["length"]>>extends true?"self":[IfPositive<Start,Start,Sum<T["length"],Start>>,End])extends infer Indexes?Indexes extends"self"?T:Indexes extends"empty"?[]:Indexes extends [infer NewStart extends number,infer NewEnd extends number]?IfGreaterOrEqual<NewStart,NewEnd>extends true?[]:FilterRemoved<{[K in keyof T]:IsArrayIndex<K>extends true?If<And<IsGreaterOrEqual<ParseNumber<K>,NewStart>,IsLowerThan<ParseNumber<K>,NewEnd>>,T[K],SliceRemovedItemValue>:T[K];}>:T:T;
3096
- /** -------------------------------------------------------
3097
- * * ***Utility Type: `Swap`.***
3098
- * -------------------------------------------------------
3099
- * **Swaps the positions of two elements in a tuple at the type level.**
3100
- * - **Behavior:**
3101
- * - Only works on tuple types. Non-tuple arrays are returned as-is.
3102
- * - Validates that `FromIndex` and `ToIndex` are within bounds of the tuple.
3103
- * - If `FromIndex` and `ToIndex` are equal, the tuple remains unchanged.
3104
- * @template T - The tuple type.
3105
- * @template FromIndex - The index of the first element to swap.
3106
- * @template ToIndex - The index of the second element to swap.
3107
- * @example
3108
- * ```ts
3109
- * // Swap first and last element
3110
- * type Case1 = Swap<[1, 2, 3], 0, 2>;
3111
- * // ➔ [3, 2, 1]
3112
- *
3113
- * // Swap same index (no change)
3114
- * type Case2 = Swap<[1, 2, 3], 0, 0>;
3115
- * // ➔ [1, 2, 3]
3116
- *
3117
- * // Swap middle elements
3118
- * type Case3 = Swap<["a", "b", "c"], 1, 2>;
3119
- * // ➔ ["a", "c", "b"]
3120
- *
3121
- * // Non-tuple array remains unchanged
3122
- * type Case4 = Swap<number[], 0, 1>;
3123
- * // ➔ number[]
3124
- * ```
3125
- */
3126
- type Swap<T extends readonly unknown[],FromIndex extends number,ToIndex extends number>=IsTuple<T>extends true?And<IsBetween<FromIndex,0,T["length"]>,IsBetween<ToIndex,0,T["length"]>>extends true?T[FromIndex] extends infer From?T[ToIndex] extends infer To?{[K in keyof T]:ParseNumber<K>extends infer NumK?IsEqual<FromIndex,NumK>extends true?To:IsEqual<ToIndex,NumK>extends true?From:T[K]:never;}:never:never:never:T;type _SortSingle<Result extends readonly number[],PivotIndex extends number,CurrentIndex extends number>=IsEqual<PivotIndex,CurrentIndex>extends true?Result:Increment<CurrentIndex>extends infer NextCurrentIndex extends number?_SortSingle<IsGreaterThan<Result[CurrentIndex],Result[NextCurrentIndex]>extends true?Swap<Result,CurrentIndex,NextCurrentIndex>extends infer NewResult extends readonly number[]?NewResult:Result:Result,PivotIndex,NextCurrentIndex>:never;type _Sort<T extends readonly number[],CurrentIndex extends number>=IsLowerOrEqual<CurrentIndex,0>extends true?T:_SortSingle<T,CurrentIndex,0>extends infer NewT extends readonly number[]?_Sort<NewT,Decrement<CurrentIndex>>:T;
3127
- /** -------------------------------------------------------
3128
- * * ***Utility Type: `Sort`.***
3129
- * -------------------------------------------------------
3130
- * **Type-level function that sorts a **tuple of numbers** in **ascending order**.**
3131
- * - **Behavior:**
3132
- * - Tuples with length `< 2` are returned as-is.
3133
- * - Works only on **tuple literal types**, not on general arrays (`number[]`).
3134
- * @template T - Tuple of numbers to sort.
3135
- * @example
3136
- * ```ts
3137
- * // Sort positive numbers
3138
- * type T0 = Sort<[3, 2, 1]>;
3139
- * // ➔ [1, 2, 3]
3140
- *
3141
- * // Sort numbers with negative values
3142
- * type T1 = Sort<[1, -1, 0]>;
3143
- * // ➔ [-1, 0, 1]
3144
- *
3145
- * // Already sorted
3146
- * type T2 = Sort<[0, 1, 2]>;
3147
- * // ➔ [0, 1, 2]
3148
- *
3149
- * // Single element tuple
3150
- * type T3 = Sort<[42]>;
3151
- * // ➔ [42]
3152
- *
3153
- * // Empty tuple
3154
- * type T4 = Sort<[]>;
3155
- * // ➔ []
3156
- * ```
3157
- */
3158
- type Sort<T extends readonly number[]>=IsLowerThan<T["length"],2>extends true?T:_Sort<T,Decrement<T["length"]>>;
3159
- /** -------------------------------------------------------
3160
- * * ***Utility Type: `StartsWith`.***
3161
- * -------------------------------------------------------
3162
- * **Type-level utility that determines whether a string `Str`
3163
- * starts with the substring `Pivot`.**
3164
- * - **Behavior:**
3165
- * - Supports `Pivot` as either `string` or `number`.
3166
- * - Returns `true` if `Str` starts with `Pivot`, otherwise `false`.
3167
- * @template Str - The string to check.
3168
- * @template Pivot - The substring or number to check as the prefix.
3169
- * @example
3170
- * ```ts
3171
- * // Check string prefix
3172
- * type Case1 = StartsWith<'abc', 'a'>;
3173
- * // ➔ true
3174
- *
3175
- * type Case2 = StartsWith<'abc', 'b'>;
3176
- * // ➔ false
3177
- *
3178
- * // Check numeric prefix
3179
- * type Case3 = StartsWith<'123', 1>;
3180
- * // ➔ true
3181
- *
3182
- * type Case4 = StartsWith<'123', 2>;
3183
- * // ➔ false
3184
- *
3185
- * // Multi-character pivot
3186
- * type Case5 = StartsWith<'typescript', 'type'>;
3187
- * // ➔ true
3188
- *
3189
- * type Case6 = StartsWith<'typescript', 'script'>;
3190
- * // ➔ false
3191
- * ```
3192
- */
3193
- type StartsWith<Str extends string,Pivot extends string|number>=Str extends`${Pivot}${string}`?true:false;
3194
- /** -------------------------------------------------------
3195
- * * ***Utility Type: `Switch`.***
3196
- * -------------------------------------------------------
3197
- * **Type-level version of a `switch` statement.**
3198
- * - **Behavior:**
3199
- * - Checks if `Condition` exists as a key in `Cases`.
3200
- * - Returns the corresponding value if the key exists.
3201
- * - Returns `Default` if the key does not exist.
3202
- * @template Condition - The value to match against case keys.
3203
- * @template Cases - An object mapping keys to corresponding values.
3204
- * @template Default - The default value returned if `Condition` is not a key in `Cases` (defaults to `never`).
3205
- * @example
3206
- * ```ts
3207
- * const a = 'const';
3208
- *
3209
- * // Matches 'const' key ➔ 'bar'
3210
- * type Result1 = Switch<typeof a, { number: 'foo', const: 'bar' }, 'foobar'>;
3211
- * // ➔ 'bar'
3212
- *
3213
- * // Condition not present ➔ returns default
3214
- * type Result2 = Switch<'other', { number: 'foo', const: 'bar' }, 'default'>;
3215
- * // ➔ 'default'
3216
- *
3217
- * // Condition present but no default specified
3218
- * type Result3 = Switch<'number', { number: 'foo', const: 'bar' }>;
3219
- * // ➔ 'foo'
3220
- * ```
3221
- */
3222
- type Switch<Condition extends PropertyKey,Cases extends Record<PropertyKey,unknown>,Default=never>=Condition extends keyof Cases?Cases[Condition]:Default;
3223
- /** -------------------------------------------------------
3224
- * * ***Utility Type: `ToPrimitive`.***
3225
- * -------------------------------------------------------
3226
- * **Converts a literal type to its corresponding primitive type.**
3227
- * - **Behavior:**
3228
- * - `string literal` ➔ `string`.
3229
- * - `number literal` ➔ `number`.
3230
- * - `boolean literal` ➔ `boolean`.
3231
- * - `bigint literal` ➔ `bigint`.
3232
- * - `symbol literal` ➔ `symbol`.
3233
- * - `null` ➔ `null`.
3234
- * - `undefined` ➔ `undefined`.
3235
- * - Objects ➔ recursively converts all properties to their primitive types.
3236
- * @template T - The literal type to convert to a primitive type.
3237
- * @example
3238
- * ```ts
3239
- * // Number literal
3240
- * type Case1 = ToPrimitive<1>;
3241
- * // ➔ number
3242
- *
3243
- * // String literal
3244
- * type Case2 = ToPrimitive<'1'>;
3245
- * // ➔ string
3246
- *
3247
- * // Boolean literal
3248
- * type Case3 = ToPrimitive<true>;
3249
- * // ➔ boolean
3250
- *
3251
- * // BigInt literal
3252
- * type Case4 = ToPrimitive<123n>;
3253
- * // ➔ bigint
3254
- *
3255
- * // Symbol literal
3256
- * type Case5 = ToPrimitive<symbol>;
3257
- * // ➔ symbol
3258
- *
3259
- * // Null and undefined
3260
- * type Case6 = ToPrimitive<null>;
3261
- * // ➔ null
3262
- * type Case7 = ToPrimitive<undefined>;
3263
- * // ➔ undefined
3264
- *
3265
- * // Object with literal properties
3266
- * type Case8 = ToPrimitive<{ a: 1; b: 's'; c: true }>;
3267
- * // ➔ { a: number; b: string; c: boolean }
3268
- * ```
3269
- */
3270
- type ToPrimitive<T>=T extends string?string:T extends number?number:T extends null?null:T extends undefined?undefined:T extends boolean?boolean:T extends bigint?bigint:T extends symbol?symbol:{[K in keyof T]:ToPrimitive<T[K]>;};
3271
- /** -------------------------------------------------------
3272
- * * ***Utility Type: `Trunc`.***
3273
- * -------------------------------------------------------
3274
- * **Type version of `Math.trunc()`.**
3275
- * @description
3276
- * Returns the **integer part** of a number by removing any fractional digits.
3277
- * - **Behavior:**
3278
- * - If `T` is a floating-point number, returns the integer part.
3279
- * - Preserves the sign for negative numbers.
3280
- * - If `T` is already an integer, returns `T`.
3281
- * - If `T` is `number` (general type), returns `T`.
3282
- * @template T - The number type to truncate.
3283
- * @example
3284
- * ```ts
3285
- * // Positive float
3286
- * type T0 = Trunc<3.14>;
3287
- * // ➔ 3
3288
- *
3289
- * // Negative float
3290
- * type T1 = Trunc<-3.14>;
3291
- * // ➔ -3
3292
- *
3293
- * // Already integer
3294
- * type T2 = Trunc<42>;
3295
- * // ➔ 42
3296
- *
3297
- * // General number type
3298
- * type T3 = Trunc<number>;
3299
- * // ➔ number
3300
- * ```
3301
- */
3302
- type Trunc<T extends number>=number extends T?T:IsFloat<T>extends true?GetFloatNumberParts<T>[0] extends infer IntegerPart extends number?IsNegative<T>extends true?Negate<IntegerPart>:IntegerPart:never:T;type FilterByType<T extends readonly unknown[],U>=T extends readonly [ infer Head,...infer Tail]?Head extends U?[Head,...FilterByType<Tail,U>]:FilterByType<Tail,U>:[];type GroupedKeys<T extends readonly PropertyKey[]>=[ ...FilterByType<T,symbol>,...FilterByType<T,string>,...FilterByType<T,number>];
3303
- /** -------------------------------------------------------
3304
- * * ***Utility Type: `TupleToObject`.***
3305
- * -------------------------------------------------------
3306
- * **Accepts a tuple of `string`, `number`, or `symbol` and returns an object type
3307
- * where each key **and its value** are the elements of the tuple.**
3308
- * - **Behavior:**
3309
- * - Tuple elements must extend `PropertyKey` (`string | number | symbol`).
3310
- * - The resulting object has keys and values identical to the tuple elements.
3311
- * @template T - The tuple of property keys.
3312
- * @example
3313
- * ```ts
3314
- * // Tuple of strings
3315
- * type T0 = TupleToObject<['foo', 'bar']>;
3316
- * // ➔ { foo: 'foo'; bar: 'bar' }
3317
- *
3318
- * // Tuple of numbers
3319
- * type T1 = TupleToObject<[1, 2, 3]>;
3320
- * // ➔ { 1: 1; 2: 2; 3: 3 }
3321
- *
3322
- * // Tuple of mixed property keys
3323
- * type T2 = TupleToObject<['a', 0, symbol]>;
3324
- * // ➔ { [x: symbol]: symbol; 0: 0; a: 'a'; }
3325
- * ```
3326
- */
3327
- type TupleToObject<T extends readonly PropertyKey[]>={[K in GroupedKeys<T>[number]]:K;};
3328
- /** -------------------------------------------------------
3329
- * * ***Utility Type: `Unshift`.***
3330
- * -------------------------------------------------------
3331
- * **Adds the specified element `U` to the **beginning** of the tuple/array `T`.**
3332
- * @template T - The original tuple or array.
3333
- * @template U - The element to add at the start.
3334
- * @example
3335
- * ```ts
3336
- * // Adding string to a tuple
3337
- * type Case1 = Unshift<['bar'], 'foo'>;
3338
- * // ➔ ['foo', 'bar']
3339
- *
3340
- * // Adding number to an empty array
3341
- * type Case2 = Unshift<[], 1>;
3342
- * // ➔ [1]
3343
- * ```
3344
- */
3345
- type Unshift<T extends readonly unknown[],U>=[U,...T];export{Abs,And,AndArr,AnyFunction,type AnyRecord,AnyString,type AnyStringRecord,type AreAnagrams,type ArgumentTypes,type ArrayElementType,type Ceil,type Color,type ColorCssNamed,type ColorOptions,type CompareNumberLength,type CompareStringLength,type Concat,type Decrement,type DeepMergeArrayUnion,type DefaultColorOptions,type DefaultHSLOptions,type DefaultNumberLengthOptions,type DefaultPathToFieldsOptions,DefaultPrettifyOptions,type DefaultRGBOptions,type DigitsTuple,type Div,type Dot,type DotArray,type EndsWith,type ExcludeStrict,Extends,ExtendsArr,type Factorial,type Fibonacci,type FirstCharacter,type FirstCharacterOptions,type FirstDigit,type Floor,type GetFloatNumberParts,type HEX,type HSL,type HSLOptions,type Identity,If,type IfColor,IfEmptyArray,IfEmptyString,type IfEqual,IfExtends,type IfGreaterOrEqual,type IfGreaterThan,type IfHEX,type IfHSL,type IfLowerOrEqual,type IfLowerThan,IfNegative,IfNever,type IfNotEqual,IfPositive,type IfRGB,type IfTuple,type Includes,type Increment,type IndexOf,IsAny,type IsArrayIndex,type IsBaseType,type IsBetween,type IsBetweenOptions,type IsColor,type IsDivisible,type IsDivisibleByFive,type IsDivisibleByHundred,type IsDivisibleBySix,type IsDivisibleByTen,type IsDivisibleByThree,type IsDivisibleByTwo,IsEmptyArray,IsEmptyString,type IsEqual,IsEven,type IsExactly,IsFloat,type IsGreaterOrEqual,type IsGreaterThan,type IsHEX,type IsHSL,IsInteger,type IsLetter,type IsLongerNumber,type IsLongerString,type IsLowerOrEqual,type IsLowerThan,IsNegative,IsNegativeInteger,IsNever,type IsNotEqual,type IsPalindrome,IsPositive,type IsRGB,IsReadonlyArray,type IsSameLengthNumber,type IsSameLengthString,type IsShorterNumber,type IsShorterString,IsStringLiteral,type IsTuple,type IsUnion,IsUnknown,type Join,type LastCharacter,type LastCharacterOptions,type LooseLiteral,type Max,type MaxArr,type Min,type MinArr,type Mod,type Multi,Negate,type NonNullableObject,type NonNullableObjectExcept,type NonNullableObjectOnly,NonUndefined,Not,NotExtends,type NumberLength,type NumberRangeLimit,Or,OrArr,ParseNumber,type PartialExcept,type PartialOnly,type PathToFields,type PathToFieldsOptions,Pop,type Pow,Prettify,PrettifyOptions,type PrettifyUnionIntersection,Push,type RGB,type RGBOptions,type ReadonlyExcept,type ReadonlyOnly,type RemoveIndexSignature,type RemoveLeading,Repeat,type Replace,type ReplaceAll,type ReplaceToPartial,type ReplaceToRequired,type RequiredExcept,type RequiredOnly,type ReturnItselfIfExtends,type ReturnItselfIfNotExtends,type Reverse,type Round,type Shift,type ShiftOptions,type Slice,type Sort,Split,type StartsWith,type StringLength,type Stringify,type Sub,type Sum,type SumArr,type Swap,type Switch,type ToPrimitive,Trim,type Trunc,type TupleToObject,type TypeNumberLengthOptions,TypedArray,type UnionToIntersection,type UnknownRecord,type Unshift,type ValueOf,type ValueOfArray,type ValueOfExcept,type ValueOfOnly};