@rzl-zone/utils-js 3.3.1 → 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.
- package/README.md +3 -3
- package/dist/assertions/index.d.ts +1 -1
- package/dist/conversions/index.d.ts +1 -1
- package/dist/formatters/index.d.ts +1 -1
- package/dist/generators/index.d.ts +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/{isPlainObject-DGJkcFYw.d.ts → isPlainObject-CEPWPiXh.d.ts} +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/operations/index.d.ts +1 -1
- package/dist/predicates/index.d.ts +1 -1
- package/dist/promises/index.d.ts +1 -1
- package/dist/strings/index.d.ts +1 -1
- package/package.json +2 -7
- package/dist/NumberRangeUnion-B6bhM2s7.d.ts +0 -33
- package/dist/any-v4TsK9ES.d.ts +0 -66
- package/dist/arrays-normalize-recursive-BqmVuFlD.d.ts +0 -72
- package/dist/extends-DtdRjDyU.d.ts +0 -343
- package/dist/if-ChM35c_q.d.ts +0 -19
- package/dist/is-array-BJeHxPM3.d.ts +0 -952
- package/dist/never-D89PbPh5.d.ts +0 -66
- package/dist/nils-CO8zLHSB.d.ts +0 -151
- package/dist/or-C6qzKt2I.d.ts +0 -82
- package/dist/override-CL2olHE5.d.ts +0 -59
- package/dist/pick-BSMX6Xe2.d.ts +0 -15
- package/dist/prettify-3o8_Kw6b.d.ts +0 -564
- package/dist/promises-LU7K00H0.d.ts +0 -72
- package/dist/string-B1jlOnws.d.ts +0 -312
- package/dist/types/index.d.ts +0 -3345
package/dist/types/index.d.ts
DELETED
|
@@ -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};
|