ts-data-forge 13.0.0 → 14.0.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 +1 -1
- package/dist/array/impl/array-utils-creation.d.mts +2 -2
- package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-creation.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts +56 -29
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +23 -15
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts +126 -28
- package/dist/array/impl/array-utils-length-bounded-array-guard.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-guard.mjs +39 -5
- package/dist/array/impl/array-utils-length-bounded-array-guard.mjs.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts +167 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.d.mts.map +1 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs +87 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-cast.mjs.map +1 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.d.mts +135 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.d.mts.map +1 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs +41 -0
- package/dist/array/impl/array-utils-length-bounded-tuple-guard.mjs.map +1 -0
- package/dist/array/impl/array-utils-modification.d.mts +32 -18
- package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.d.mts +3 -3
- package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
- package/dist/array/impl/array-utils-slicing.d.mts +11 -11
- package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
- package/dist/array/impl/array-utils-slicing.mjs +1 -1
- package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts +35 -23
- package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-transformation.mjs +2 -2
- package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
- package/dist/array/impl/array-utils-validation.d.mts +2 -124
- package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-validation.mjs +1 -7
- package/dist/array/impl/array-utils-validation.mjs.map +1 -1
- package/dist/array/impl/index.d.mts +2 -0
- package/dist/array/impl/index.d.mts.map +1 -1
- package/dist/array/impl/index.mjs +5 -3
- package/dist/array/impl/index.mjs.map +1 -1
- package/dist/object/object.mjs +1 -1
- package/dist/string/str.d.mts +44 -44
- package/dist/string/str.d.mts.map +1 -1
- package/dist/string/str.mjs +17 -17
- package/dist/string/str.mjs.map +1 -1
- package/package.json +2 -2
- package/src/array/impl/array-utils-creation.mts +7 -3
- package/src/array/impl/array-utils-length-bounded-array-cast.mts +88 -50
- package/src/array/impl/array-utils-length-bounded-array-cast.test.mts +40 -13
- package/src/array/impl/array-utils-length-bounded-array-guard.mts +248 -39
- package/src/array/impl/array-utils-length-bounded-array-guard.test.mts +135 -24
- package/src/array/impl/array-utils-length-bounded-tuple-cast.mts +364 -0
- package/src/array/impl/array-utils-length-bounded-tuple-cast.test.mts +207 -0
- package/src/array/impl/array-utils-length-bounded-tuple-guard.mts +266 -0
- package/src/array/impl/array-utils-length-bounded-tuple-guard.test.mts +441 -0
- package/src/array/impl/array-utils-length-constraint-preservation.test.mts +287 -0
- package/src/array/impl/array-utils-modification.mts +72 -57
- package/src/array/impl/array-utils-modification.test.mts +93 -6
- package/src/array/impl/array-utils-reducing-value.mts +5 -5
- package/src/array/impl/array-utils-slicing.mts +65 -43
- package/src/array/impl/array-utils-slicing.test.mts +55 -0
- package/src/array/impl/array-utils-transformation.mts +66 -39
- package/src/array/impl/array-utils-transformation.test.mts +62 -16
- package/src/array/impl/array-utils-validation.mts +2 -162
- package/src/array/impl/array-utils-validation.test.mts +0 -371
- package/src/array/impl/index.mts +2 -0
- package/src/collections/queue.test.mts +1 -1
- package/src/string/str.mts +69 -69
- package/src/string/str.test.mts +40 -40
package/dist/string/str.d.mts
CHANGED
|
@@ -25,25 +25,25 @@ export declare namespace Str {
|
|
|
25
25
|
* ```ts
|
|
26
26
|
* const input: string = 'very-secret-password';
|
|
27
27
|
*
|
|
28
|
-
* assert.isTrue(Str.isMinLengthString(
|
|
28
|
+
* assert.isTrue(Str.isMinLengthString(12, input));
|
|
29
29
|
*
|
|
30
|
-
* assert.isFalse(Str.isMinLengthString('short'
|
|
30
|
+
* assert.isFalse(Str.isMinLengthString(12, 'short'));
|
|
31
31
|
*
|
|
32
|
-
* if (Str.isMinLengthString(
|
|
32
|
+
* if (Str.isMinLengthString(12, input)) {
|
|
33
33
|
* const nonEmpty: NonEmptyString = input; // OK (12 >= 1)
|
|
34
34
|
*
|
|
35
35
|
* assert.isTrue(nonEmpty.length >= 12);
|
|
36
36
|
* }
|
|
37
37
|
* ```
|
|
38
38
|
*
|
|
39
|
-
* @template S - The input string type (literal types are preserved).
|
|
40
39
|
* @template MinLength - The minimum number of characters (inclusive).
|
|
41
|
-
* @
|
|
40
|
+
* @template S - The input string type (literal types are preserved).
|
|
42
41
|
* @param minLength - The minimum number of characters (inclusive).
|
|
42
|
+
* @param s - The string to check.
|
|
43
43
|
* @returns `true` if `s.length >= minLength`, `false` otherwise. When `true`,
|
|
44
44
|
* TypeScript narrows `s` to `MinLengthString<MinLength> & S`.
|
|
45
45
|
*/
|
|
46
|
-
const isMinLengthString: <
|
|
46
|
+
const isMinLengthString: <MinLength extends SupportedLength, S extends string>(minLength: MinLength, s: S) => s is MinLengthString<MinLength> & S;
|
|
47
47
|
/**
|
|
48
48
|
* Type guard that checks if a string has at most `maxLength` characters.
|
|
49
49
|
*
|
|
@@ -60,25 +60,25 @@ export declare namespace Str {
|
|
|
60
60
|
* ```ts
|
|
61
61
|
* const input: string = 'noshiro';
|
|
62
62
|
*
|
|
63
|
-
* assert.isTrue(Str.isMaxLengthString(
|
|
63
|
+
* assert.isTrue(Str.isMaxLengthString(32, input));
|
|
64
64
|
*
|
|
65
|
-
* assert.isFalse(Str.isMaxLengthString(
|
|
65
|
+
* assert.isFalse(Str.isMaxLengthString(3, input));
|
|
66
66
|
*
|
|
67
|
-
* if (Str.isMaxLengthString(
|
|
67
|
+
* if (Str.isMaxLengthString(32, input)) {
|
|
68
68
|
* const relaxed: MaxLengthString<64> = input; // OK (32 <= 64)
|
|
69
69
|
*
|
|
70
70
|
* assert.isTrue(relaxed.length <= 32);
|
|
71
71
|
* }
|
|
72
72
|
* ```
|
|
73
73
|
*
|
|
74
|
-
* @template S - The input string type (literal types are preserved).
|
|
75
74
|
* @template MaxLength - The maximum number of characters (inclusive).
|
|
76
|
-
* @
|
|
75
|
+
* @template S - The input string type (literal types are preserved).
|
|
77
76
|
* @param maxLength - The maximum number of characters (inclusive).
|
|
77
|
+
* @param s - The string to check.
|
|
78
78
|
* @returns `true` if `s.length <= maxLength`, `false` otherwise. When `true`,
|
|
79
79
|
* TypeScript narrows `s` to `MaxLengthString<MaxLength> & S`.
|
|
80
80
|
*/
|
|
81
|
-
const isMaxLengthString: <
|
|
81
|
+
const isMaxLengthString: <MaxLength extends SupportedLength, S extends string>(maxLength: MaxLength, s: S) => s is MaxLengthString<MaxLength> & S;
|
|
82
82
|
/**
|
|
83
83
|
* Type guard that checks if a string's length is within the inclusive range
|
|
84
84
|
* `[minLength, maxLength]`.
|
|
@@ -96,28 +96,28 @@ export declare namespace Str {
|
|
|
96
96
|
* ```ts
|
|
97
97
|
* const input: string = 'user-12345678';
|
|
98
98
|
*
|
|
99
|
-
* assert.isTrue(Str.isBoundedLengthString(
|
|
99
|
+
* assert.isTrue(Str.isBoundedLengthString(8, 16, input));
|
|
100
100
|
*
|
|
101
|
-
* assert.isFalse(Str.isBoundedLengthString(
|
|
101
|
+
* assert.isFalse(Str.isBoundedLengthString(8, 16, 'user'));
|
|
102
102
|
*
|
|
103
|
-
* if (Str.isBoundedLengthString(
|
|
103
|
+
* if (Str.isBoundedLengthString(8, 16, input)) {
|
|
104
104
|
* const userId: BoundedLengthString<1, 255> = input; // OK ([8, 16] ⊆ [1, 255])
|
|
105
105
|
*
|
|
106
106
|
* assert.isTrue(userId.length >= 8 && userId.length <= 16);
|
|
107
107
|
* }
|
|
108
108
|
* ```
|
|
109
109
|
*
|
|
110
|
-
* @template S - The input string type (literal types are preserved).
|
|
111
110
|
* @template MinLength - The minimum number of characters (inclusive).
|
|
112
111
|
* @template MaxLength - The maximum number of characters (inclusive).
|
|
113
|
-
* @
|
|
112
|
+
* @template S - The input string type (literal types are preserved).
|
|
114
113
|
* @param minLength - The minimum number of characters (inclusive).
|
|
115
114
|
* @param maxLength - The maximum number of characters (inclusive).
|
|
115
|
+
* @param s - The string to check.
|
|
116
116
|
* @returns `true` if `minLength <= s.length && s.length <= maxLength`, `false`
|
|
117
117
|
* otherwise. When `true`, TypeScript narrows `s` to
|
|
118
118
|
* `BoundedLengthString<MinLength, MaxLength> & S`.
|
|
119
119
|
*/
|
|
120
|
-
const isBoundedLengthString: <
|
|
120
|
+
const isBoundedLengthString: <MinLength extends SupportedLength, MaxLength extends SupportedLength, S extends string>(minLength: MinLength, maxLength: MaxLength, s: S) => s is BoundedLengthString<MinLength, MaxLength> & S;
|
|
121
121
|
/**
|
|
122
122
|
* Type guard that checks if a string has exactly `length` characters.
|
|
123
123
|
*
|
|
@@ -135,25 +135,25 @@ export declare namespace Str {
|
|
|
135
135
|
* ```ts
|
|
136
136
|
* const input: string = 'JP';
|
|
137
137
|
*
|
|
138
|
-
* assert.isTrue(Str.isFixedLengthString(
|
|
138
|
+
* assert.isTrue(Str.isFixedLengthString(2, input));
|
|
139
139
|
*
|
|
140
|
-
* assert.isFalse(Str.isFixedLengthString(
|
|
140
|
+
* assert.isFalse(Str.isFixedLengthString(3, input));
|
|
141
141
|
*
|
|
142
|
-
* if (Str.isFixedLengthString(
|
|
142
|
+
* if (Str.isFixedLengthString(2, input)) {
|
|
143
143
|
* const atMost5: MaxLengthString<5> = input; // OK (2 <= 5)
|
|
144
144
|
*
|
|
145
145
|
* assert.isTrue(atMost5.length === 2);
|
|
146
146
|
* }
|
|
147
147
|
* ```
|
|
148
148
|
*
|
|
149
|
-
* @template S - The input string type (literal types are preserved).
|
|
150
149
|
* @template Length - The exact number of characters.
|
|
151
|
-
* @
|
|
150
|
+
* @template S - The input string type (literal types are preserved).
|
|
152
151
|
* @param length - The exact number of characters.
|
|
152
|
+
* @param s - The string to check.
|
|
153
153
|
* @returns `true` if `s.length === length`, `false` otherwise. When `true`,
|
|
154
154
|
* TypeScript narrows `s` to `FixedLengthString<Length> & S`.
|
|
155
155
|
*/
|
|
156
|
-
const isFixedLengthString: <
|
|
156
|
+
const isFixedLengthString: <Length extends SupportedLength, S extends string>(length: Length, s: S) => s is FixedLengthString<Length> & S;
|
|
157
157
|
/**
|
|
158
158
|
* Casts a string to `MinLengthString<MinLength>` after checking that it has
|
|
159
159
|
* at least `minLength` characters.
|
|
@@ -168,7 +168,7 @@ export declare namespace Str {
|
|
|
168
168
|
* @example
|
|
169
169
|
*
|
|
170
170
|
* ```ts
|
|
171
|
-
* const password = Str.asMinLengthString('very-secret-password'
|
|
171
|
+
* const password = Str.asMinLengthString(12, 'very-secret-password');
|
|
172
172
|
*
|
|
173
173
|
* const nonEmpty: NonEmptyString = password; // OK (>= 1)
|
|
174
174
|
*
|
|
@@ -179,17 +179,17 @@ export declare namespace Str {
|
|
|
179
179
|
*
|
|
180
180
|
* assert.strictEqual(asPassword('another-secret'), 'another-secret');
|
|
181
181
|
*
|
|
182
|
-
* assert.throws(() => Str.asMinLengthString('short'
|
|
182
|
+
* assert.throws(() => Str.asMinLengthString(12, 'short')); // length 5 < 12
|
|
183
183
|
* ```
|
|
184
184
|
*
|
|
185
|
-
* @template S - The input string type (literal types are preserved).
|
|
186
185
|
* @template MinLength - The minimum number of characters (inclusive).
|
|
187
|
-
* @
|
|
186
|
+
* @template S - The input string type (literal types are preserved).
|
|
188
187
|
* @param minLength - The minimum number of characters (inclusive).
|
|
188
|
+
* @param s - The string to cast.
|
|
189
189
|
* @returns `s` typed as `MinLengthString<MinLength> & S`.
|
|
190
190
|
* @throws {TypeError} If `s.length < minLength`.
|
|
191
191
|
*/
|
|
192
|
-
function asMinLengthString<
|
|
192
|
+
function asMinLengthString<MinLength extends SupportedLength, S extends string>(minLength: MinLength, s: S): MinLengthString<MinLength> & S;
|
|
193
193
|
function asMinLengthString<MinLength extends SupportedLength>(minLength: MinLength): <S extends string>(s: S) => MinLengthString<MinLength> & S;
|
|
194
194
|
/**
|
|
195
195
|
* Casts a string to `MaxLengthString<MaxLength>` after checking that it has
|
|
@@ -205,7 +205,7 @@ export declare namespace Str {
|
|
|
205
205
|
* @example
|
|
206
206
|
*
|
|
207
207
|
* ```ts
|
|
208
|
-
* const userName = Str.asMaxLengthString('noshiro'
|
|
208
|
+
* const userName = Str.asMaxLengthString(32, 'noshiro');
|
|
209
209
|
*
|
|
210
210
|
* const relaxed: MaxLengthString<64> = userName; // OK (32 <= 64)
|
|
211
211
|
*
|
|
@@ -216,17 +216,17 @@ export declare namespace Str {
|
|
|
216
216
|
*
|
|
217
217
|
* assert.strictEqual(asUserName('another-user'), 'another-user');
|
|
218
218
|
*
|
|
219
|
-
* assert.throws(() => Str.asMaxLengthString('noshiro'
|
|
219
|
+
* assert.throws(() => Str.asMaxLengthString(3, 'noshiro')); // length 7 > 3
|
|
220
220
|
* ```
|
|
221
221
|
*
|
|
222
|
-
* @template S - The input string type (literal types are preserved).
|
|
223
222
|
* @template MaxLength - The maximum number of characters (inclusive).
|
|
224
|
-
* @
|
|
223
|
+
* @template S - The input string type (literal types are preserved).
|
|
225
224
|
* @param maxLength - The maximum number of characters (inclusive).
|
|
225
|
+
* @param s - The string to cast.
|
|
226
226
|
* @returns `s` typed as `MaxLengthString<MaxLength> & S`.
|
|
227
227
|
* @throws {TypeError} If `s.length > maxLength`.
|
|
228
228
|
*/
|
|
229
|
-
function asMaxLengthString<
|
|
229
|
+
function asMaxLengthString<MaxLength extends SupportedLength, S extends string>(maxLength: MaxLength, s: S): MaxLengthString<MaxLength> & S;
|
|
230
230
|
function asMaxLengthString<MaxLength extends SupportedLength>(maxLength: MaxLength): <S extends string>(s: S) => MaxLengthString<MaxLength> & S;
|
|
231
231
|
/**
|
|
232
232
|
* Casts a string to `BoundedLengthString<MinLength, MaxLength>` after
|
|
@@ -244,7 +244,7 @@ export declare namespace Str {
|
|
|
244
244
|
* @example
|
|
245
245
|
*
|
|
246
246
|
* ```ts
|
|
247
|
-
* const userId = Str.asBoundedLengthString('user-12345678'
|
|
247
|
+
* const userId = Str.asBoundedLengthString(8, 16, 'user-12345678');
|
|
248
248
|
*
|
|
249
249
|
* const relaxed: BoundedLengthString<1, 255> = userId; // OK ([8, 16] ⊆ [1, 255])
|
|
250
250
|
*
|
|
@@ -255,19 +255,19 @@ export declare namespace Str {
|
|
|
255
255
|
*
|
|
256
256
|
* assert.strictEqual(asUserId('user-87654321'), 'user-87654321');
|
|
257
257
|
*
|
|
258
|
-
* assert.throws(() => Str.asBoundedLengthString(
|
|
258
|
+
* assert.throws(() => Str.asBoundedLengthString(8, 16, 'user')); // length 4 < 8
|
|
259
259
|
* ```
|
|
260
260
|
*
|
|
261
|
-
* @template S - The input string type (literal types are preserved).
|
|
262
261
|
* @template MinLength - The minimum number of characters (inclusive).
|
|
263
262
|
* @template MaxLength - The maximum number of characters (inclusive).
|
|
264
|
-
* @
|
|
263
|
+
* @template S - The input string type (literal types are preserved).
|
|
265
264
|
* @param minLength - The minimum number of characters (inclusive).
|
|
266
265
|
* @param maxLength - The maximum number of characters (inclusive).
|
|
266
|
+
* @param s - The string to cast.
|
|
267
267
|
* @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.
|
|
268
268
|
* @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.
|
|
269
269
|
*/
|
|
270
|
-
function asBoundedLengthString<
|
|
270
|
+
function asBoundedLengthString<MinLength extends SupportedLength, MaxLength extends SupportedLength, S extends string>(minLength: MinLength, maxLength: MaxLength, s: S): BoundedLengthString<MinLength, MaxLength> & S;
|
|
271
271
|
function asBoundedLengthString<MinLength extends SupportedLength, MaxLength extends SupportedLength>(minLength: MinLength, maxLength: MaxLength): <S extends string>(s: S) => BoundedLengthString<MinLength, MaxLength> & S;
|
|
272
272
|
/**
|
|
273
273
|
* Casts a string to `FixedLengthString<Length>` after checking that it has
|
|
@@ -283,7 +283,7 @@ export declare namespace Str {
|
|
|
283
283
|
* @example
|
|
284
284
|
*
|
|
285
285
|
* ```ts
|
|
286
|
-
* const countryCode = Str.asFixedLengthString('JP'
|
|
286
|
+
* const countryCode = Str.asFixedLengthString(2, 'JP');
|
|
287
287
|
*
|
|
288
288
|
* const atMost5: MaxLengthString<5> = countryCode; // OK (2 <= 5)
|
|
289
289
|
*
|
|
@@ -294,17 +294,17 @@ export declare namespace Str {
|
|
|
294
294
|
*
|
|
295
295
|
* assert.strictEqual(asCountryCode('US'), 'US');
|
|
296
296
|
*
|
|
297
|
-
* assert.throws(() => Str.asFixedLengthString('JP'
|
|
297
|
+
* assert.throws(() => Str.asFixedLengthString(3, 'JP')); // length 2 !== 3
|
|
298
298
|
* ```
|
|
299
299
|
*
|
|
300
|
-
* @template S - The input string type (literal types are preserved).
|
|
301
300
|
* @template Length - The exact number of characters.
|
|
302
|
-
* @
|
|
301
|
+
* @template S - The input string type (literal types are preserved).
|
|
303
302
|
* @param length - The exact number of characters.
|
|
303
|
+
* @param s - The string to cast.
|
|
304
304
|
* @returns `s` typed as `FixedLengthString<Length> & S`.
|
|
305
305
|
* @throws {TypeError} If `s.length !== length`.
|
|
306
306
|
*/
|
|
307
|
-
function asFixedLengthString<
|
|
307
|
+
function asFixedLengthString<Length extends SupportedLength, S extends string>(length: Length, s: S): FixedLengthString<Length> & S;
|
|
308
308
|
function asFixedLengthString<Length extends SupportedLength>(length: Length): <S extends string>(s: S) => FixedLengthString<Length> & S;
|
|
309
309
|
/**
|
|
310
310
|
* Casts a string to `NonEmptyString` after checking that it has at least one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str.d.mts","sourceRoot":"","sources":["../../src/string/str.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB;;;;;;;;GAQG;AACH,yBAAiB,GAAG,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACI,MAAM,iBAAiB,GAC5B,
|
|
1
|
+
{"version":3,"file":"str.d.mts","sourceRoot":"","sources":["../../src/string/str.mts"],"names":[],"mappings":"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"}
|
package/dist/string/str.mjs
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
var Str;
|
|
2
2
|
((Str2) => {
|
|
3
|
-
Str2.isMinLengthString = (
|
|
4
|
-
Str2.isMaxLengthString = (
|
|
5
|
-
Str2.isBoundedLengthString = (
|
|
6
|
-
Str2.isFixedLengthString = (
|
|
3
|
+
Str2.isMinLengthString = (minLength, s) => s.length >= minLength;
|
|
4
|
+
Str2.isMaxLengthString = (maxLength, s) => s.length <= maxLength;
|
|
5
|
+
Str2.isBoundedLengthString = (minLength, maxLength, s) => s.length >= minLength && s.length <= maxLength;
|
|
6
|
+
Str2.isFixedLengthString = (length, s) => s.length === length;
|
|
7
7
|
function asMinLengthString(...args) {
|
|
8
8
|
switch (args.length) {
|
|
9
9
|
case 2:
|
|
10
10
|
return asMinLengthStringImpl(...args);
|
|
11
11
|
case 1:
|
|
12
|
-
return (s) => asMinLengthStringImpl(
|
|
12
|
+
return (s) => asMinLengthStringImpl(args[0], s);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
Str2.asMinLengthString = asMinLengthString;
|
|
16
|
-
const asMinLengthStringImpl = (
|
|
16
|
+
const asMinLengthStringImpl = (minLength, s) => {
|
|
17
17
|
const actualLength = s.length;
|
|
18
|
-
if (!(0, Str2.isMinLengthString)(
|
|
18
|
+
if (!(0, Str2.isMinLengthString)(minLength, s)) {
|
|
19
19
|
throw new TypeError(
|
|
20
20
|
`Expected a string of length >= ${minLength}, got a string of length ${actualLength}`
|
|
21
21
|
);
|
|
@@ -27,13 +27,13 @@ var Str;
|
|
|
27
27
|
case 2:
|
|
28
28
|
return asMaxLengthStringImpl(...args);
|
|
29
29
|
case 1:
|
|
30
|
-
return (s) => asMaxLengthStringImpl(
|
|
30
|
+
return (s) => asMaxLengthStringImpl(args[0], s);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
Str2.asMaxLengthString = asMaxLengthString;
|
|
34
|
-
const asMaxLengthStringImpl = (
|
|
34
|
+
const asMaxLengthStringImpl = (maxLength, s) => {
|
|
35
35
|
const actualLength = s.length;
|
|
36
|
-
if (!(0, Str2.isMaxLengthString)(
|
|
36
|
+
if (!(0, Str2.isMaxLengthString)(maxLength, s)) {
|
|
37
37
|
throw new TypeError(
|
|
38
38
|
`Expected a string of length <= ${maxLength}, got a string of length ${actualLength}`
|
|
39
39
|
);
|
|
@@ -45,13 +45,13 @@ var Str;
|
|
|
45
45
|
case 3:
|
|
46
46
|
return asBoundedLengthStringImpl(...args);
|
|
47
47
|
case 2:
|
|
48
|
-
return (s) => asBoundedLengthStringImpl(
|
|
48
|
+
return (s) => asBoundedLengthStringImpl(...args, s);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
Str2.asBoundedLengthString = asBoundedLengthString;
|
|
52
|
-
const asBoundedLengthStringImpl = (
|
|
52
|
+
const asBoundedLengthStringImpl = (minLength, maxLength, s) => {
|
|
53
53
|
const actualLength = s.length;
|
|
54
|
-
if (!(0, Str2.isBoundedLengthString)(
|
|
54
|
+
if (!(0, Str2.isBoundedLengthString)(minLength, maxLength, s)) {
|
|
55
55
|
throw new TypeError(
|
|
56
56
|
`Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${actualLength}`
|
|
57
57
|
);
|
|
@@ -63,13 +63,13 @@ var Str;
|
|
|
63
63
|
case 2:
|
|
64
64
|
return asFixedLengthStringImpl(...args);
|
|
65
65
|
case 1:
|
|
66
|
-
return (s) => asFixedLengthStringImpl(
|
|
66
|
+
return (s) => asFixedLengthStringImpl(args[0], s);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
Str2.asFixedLengthString = asFixedLengthString;
|
|
70
|
-
const asFixedLengthStringImpl = (
|
|
70
|
+
const asFixedLengthStringImpl = (length, s) => {
|
|
71
71
|
const actualLength = s.length;
|
|
72
|
-
if (!(0, Str2.isFixedLengthString)(
|
|
72
|
+
if (!(0, Str2.isFixedLengthString)(length, s)) {
|
|
73
73
|
throw new TypeError(
|
|
74
74
|
`Expected a string of length ${length}, got a string of length ${actualLength}`
|
|
75
75
|
);
|
|
@@ -77,7 +77,7 @@ var Str;
|
|
|
77
77
|
return s;
|
|
78
78
|
};
|
|
79
79
|
Str2.asNonEmptyString = (s) => {
|
|
80
|
-
if (!(0, Str2.isMinLengthString)(
|
|
80
|
+
if (!(0, Str2.isMinLengthString)(1, s)) {
|
|
81
81
|
throw new TypeError("Expected a non-empty string, got an empty string");
|
|
82
82
|
}
|
|
83
83
|
return s;
|
package/dist/string/str.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str.mjs","sources":["../../src/string/str.mts"],"sourcesContent":["import {\n type BoundedLengthString,\n type FixedLengthString,\n type MaxLengthString,\n type MinLengthString,\n type NonEmptyString,\n type SupportedLength,\n} from 'ts-type-forge';\n\n/**\n * Namespace providing type guards and runtime-checked casts for the branded\n * length-constrained string types (`MinLengthString`, `MaxLengthString`,\n * `BoundedLengthString`, `FixedLengthString`).\n *\n * Lengths are measured in UTF-16 code units (the same unit as\n * `String.prototype.length`), so characters outside the Basic Multilingual\n * Plane (e.g. emoji) count as 2.\n */\nexport namespace Str {\n /**\n * Type guard that checks if a string has at least `minLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MinLengthString<MinLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MinLengthString<3>` is assignable to\n * `MinLengthString<1>` (= `NonEmptyString`).\n *\n * @example\n *\n * ```ts\n * const input: string = 'very-secret-password';\n *\n * assert.isTrue(Str.isMinLengthString(input, 12));\n *\n * assert.isFalse(Str.isMinLengthString('short', 12));\n *\n * if (Str.isMinLengthString(input, 12)) {\n * const nonEmpty: NonEmptyString = input; // OK (12 >= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `true` if `s.length >= minLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MinLengthString<MinLength> & S`.\n */\n export const isMinLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n ): s is MinLengthString<MinLength> & S => s.length >= minLength;\n\n /**\n * Type guard that checks if a string has at most `maxLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MaxLengthString<MaxLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MaxLengthString<16>` is assignable to\n * `MaxLengthString<32>`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'noshiro';\n *\n * assert.isTrue(Str.isMaxLengthString(input, 32));\n *\n * assert.isFalse(Str.isMaxLengthString(input, 3));\n *\n * if (Str.isMaxLengthString(input, 32)) {\n * const relaxed: MaxLengthString<64> = input; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `s.length <= maxLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MaxLengthString<MaxLength> & S`.\n */\n export const isMaxLengthString = <\n S extends string,\n MaxLength extends SupportedLength,\n >(\n s: S,\n maxLength: MaxLength,\n ): s is MaxLengthString<MaxLength> & S => s.length <= maxLength;\n\n /**\n * Type guard that checks if a string's length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `BoundedLengthString<MinLength, MaxLength>` while\n * preserving the original string type (e.g. literal types) via intersection.\n * - Since `BoundedLengthString` is the intersection of `MinLengthString` and\n * `MaxLengthString`, the narrowed value is assignable to both, and both\n * bounds can be weakened independently.\n *\n * @example\n *\n * ```ts\n * const input: string = 'user-12345678';\n *\n * assert.isTrue(Str.isBoundedLengthString(input, 8, 16));\n *\n * assert.isFalse(Str.isBoundedLengthString('user', 8, 16));\n *\n * if (Str.isBoundedLengthString(input, 8, 16)) {\n * const userId: BoundedLengthString<1, 255> = input; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(userId.length >= 8 && userId.length <= 16);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `minLength <= s.length && s.length <= maxLength`, `false`\n * otherwise. When `true`, TypeScript narrows `s` to\n * `BoundedLengthString<MinLength, MaxLength> & S`.\n */\n export const isBoundedLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): s is BoundedLengthString<MinLength, MaxLength> & S =>\n s.length >= minLength && s.length <= maxLength;\n\n /**\n * Type guard that checks if a string has exactly `length` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `FixedLengthString<Length>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - Since `FixedLengthString<Length>` is defined as\n * `BoundedLengthString<Length, Length>`, the narrowed value is assignable to\n * any `MinLengthString<N>` with `N <= Length` and any `MaxLengthString<N>`\n * with `N >= Length`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'JP';\n *\n * assert.isTrue(Str.isFixedLengthString(input, 2));\n *\n * assert.isFalse(Str.isFixedLengthString(input, 3));\n *\n * if (Str.isFixedLengthString(input, 2)) {\n * const atMost5: MaxLengthString<5> = input; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to check.\n * @param length - The exact number of characters.\n * @returns `true` if `s.length === length`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `FixedLengthString<Length> & S`.\n */\n export const isFixedLengthString = <\n S extends string,\n Length extends SupportedLength,\n >(\n s: S,\n length: Length,\n ): s is FixedLengthString<Length> & S => s.length === length;\n\n /**\n * Casts a string to `MinLengthString<MinLength>` after checking that it has\n * at least `minLength` characters.\n *\n * Use this instead of writing `s as unknown as MinLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const password = Str.asMinLengthString('very-secret-password', 12);\n *\n * const nonEmpty: NonEmptyString = password; // OK (>= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n *\n * // curried version\n * const asPassword = Str.asMinLengthString(12);\n *\n * assert.strictEqual(asPassword('another-secret'), 'another-secret');\n *\n * assert.throws(() => Str.asMinLengthString('short', 12)); // length 5 < 12\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `s` typed as `MinLengthString<MinLength> & S`.\n * @throws {TypeError} If `s.length < minLength`.\n */\n export function asMinLengthString<\n S extends string,\n MinLength extends SupportedLength,\n >(s: S, minLength: MinLength): MinLengthString<MinLength> & S;\n\n // Curried version\n export function asMinLengthString<MinLength extends SupportedLength>(\n minLength: MinLength,\n ): <S extends string>(s: S) => MinLengthString<MinLength> & S;\n\n export function asMinLengthString(\n ...args:\n | readonly [s: string, minLength: SupportedLength]\n | readonly [minLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asMinLengthStringImpl(...args);\n\n case 1:\n return (s) => asMinLengthStringImpl(s, ...args);\n }\n }\n\n const asMinLengthStringImpl = (\n s: string,\n minLength: SupportedLength,\n ): string => {\n const actualLength = s.length;\n\n if (!isMinLengthString(s, minLength)) {\n throw new TypeError(\n `Expected a string of length >= ${minLength}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `MaxLengthString<MaxLength>` after checking that it has\n * at most `maxLength` characters.\n *\n * Use this instead of writing `s as unknown as MaxLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `maxLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userName = Str.asMaxLengthString('noshiro', 32);\n *\n * const relaxed: MaxLengthString<64> = userName; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n *\n * // curried version\n * const asUserName = Str.asMaxLengthString(32);\n *\n * assert.strictEqual(asUserName('another-user'), 'another-user');\n *\n * assert.throws(() => Str.asMaxLengthString('noshiro', 3)); // length 7 > 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `MaxLengthString<MaxLength> & S`.\n * @throws {TypeError} If `s.length > maxLength`.\n */\n export function asMaxLengthString<\n S extends string,\n MaxLength extends SupportedLength,\n >(s: S, maxLength: MaxLength): MaxLengthString<MaxLength> & S;\n\n // Curried version\n export function asMaxLengthString<MaxLength extends SupportedLength>(\n maxLength: MaxLength,\n ): <S extends string>(s: S) => MaxLengthString<MaxLength> & S;\n\n export function asMaxLengthString(\n ...args:\n | readonly [s: string, maxLength: SupportedLength]\n | readonly [maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asMaxLengthStringImpl(...args);\n\n case 1:\n return (s) => asMaxLengthStringImpl(s, ...args);\n }\n }\n\n const asMaxLengthStringImpl = (\n s: string,\n maxLength: SupportedLength,\n ): string => {\n const actualLength = s.length;\n\n if (!isMaxLengthString(s, maxLength)) {\n throw new TypeError(\n `Expected a string of length <= ${maxLength}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `BoundedLengthString<MinLength, MaxLength>` after\n * checking that its length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * Use this instead of writing `s as unknown as BoundedLengthString<M, N>`:\n * the length is verified at runtime, and the original string type (e.g.\n * literal types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` and\n * `maxLength` returns a function that casts a string, which is convenient for\n * `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userId = Str.asBoundedLengthString('user-12345678', 8, 16);\n *\n * const relaxed: BoundedLengthString<1, 255> = userId; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(relaxed.length >= 8 && relaxed.length <= 16);\n *\n * // curried version\n * const asUserId = Str.asBoundedLengthString(8, 16);\n *\n * assert.strictEqual(asUserId('user-87654321'), 'user-87654321');\n *\n * assert.throws(() => Str.asBoundedLengthString('user', 8, 16)); // length 4 < 8\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.\n * @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.\n */\n export function asBoundedLengthString<\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): BoundedLengthString<MinLength, MaxLength> & S;\n\n // Curried version\n export function asBoundedLengthString<\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n minLength: MinLength,\n maxLength: MaxLength,\n ): <S extends string>(s: S) => BoundedLengthString<MinLength, MaxLength> & S;\n\n export function asBoundedLengthString(\n ...args:\n | readonly [\n s: string,\n minLength: SupportedLength,\n maxLength: SupportedLength,\n ]\n | readonly [minLength: SupportedLength, maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 3:\n return asBoundedLengthStringImpl(...args);\n\n case 2:\n return (s) => asBoundedLengthStringImpl(s, ...args);\n }\n }\n\n const asBoundedLengthStringImpl = (\n s: string,\n minLength: SupportedLength,\n maxLength: SupportedLength,\n ): string => {\n const actualLength = s.length;\n\n if (!isBoundedLengthString(s, minLength, maxLength)) {\n throw new TypeError(\n `Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `FixedLengthString<Length>` after checking that it has\n * exactly `length` characters.\n *\n * Use this instead of writing `s as unknown as FixedLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `length` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const countryCode = Str.asFixedLengthString('JP', 2);\n *\n * const atMost5: MaxLengthString<5> = countryCode; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n *\n * // curried version\n * const asCountryCode = Str.asFixedLengthString(2);\n *\n * assert.strictEqual(asCountryCode('US'), 'US');\n *\n * assert.throws(() => Str.asFixedLengthString('JP', 3)); // length 2 !== 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to cast.\n * @param length - The exact number of characters.\n * @returns `s` typed as `FixedLengthString<Length> & S`.\n * @throws {TypeError} If `s.length !== length`.\n */\n export function asFixedLengthString<\n S extends string,\n Length extends SupportedLength,\n >(s: S, length: Length): FixedLengthString<Length> & S;\n\n // Curried version\n export function asFixedLengthString<Length extends SupportedLength>(\n length: Length,\n ): <S extends string>(s: S) => FixedLengthString<Length> & S;\n\n export function asFixedLengthString(\n ...args:\n | readonly [s: string, length: SupportedLength]\n | readonly [length: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asFixedLengthStringImpl(...args);\n\n case 1:\n return (s) => asFixedLengthStringImpl(s, ...args);\n }\n }\n\n const asFixedLengthStringImpl = (\n s: string,\n length: SupportedLength,\n ): string => {\n const actualLength = s.length;\n\n if (!isFixedLengthString(s, length)) {\n throw new TypeError(\n `Expected a string of length ${length}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `NonEmptyString` after checking that it has at least one\n * character.\n *\n * `NonEmptyString` is an alias of `MinLengthString<1>`, so this is the\n * length-1 specialization of {@link asMinLengthString}. Use this instead of\n * writing `s as unknown as NonEmptyString`: the length is verified at\n * runtime, and the original string type (e.g. literal types) is preserved\n * via intersection.\n *\n * @example\n *\n * ```ts\n * const name = Str.asNonEmptyString('noshiro');\n *\n * const nonEmpty: NonEmptyString = name; // OK\n *\n * assert.isTrue(nonEmpty.length >= 1);\n *\n * assert.throws(() => Str.asNonEmptyString('')); // length 0 < 1\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @param s - The string to cast.\n * @returns `s` typed as `NonEmptyString & S`.\n * @throws {TypeError} If `s` is empty.\n */\n export const asNonEmptyString = <S extends string>(\n s: S,\n ): NonEmptyString & S => {\n if (!isMinLengthString(s, 1)) {\n throw new TypeError('Expected a non-empty string, got an empty string');\n }\n\n return s;\n };\n}\n"],"names":["Str"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"str.mjs","sources":["../../src/string/str.mts"],"sourcesContent":["import {\n type BoundedLengthString,\n type FixedLengthString,\n type MaxLengthString,\n type MinLengthString,\n type NonEmptyString,\n type SupportedLength,\n} from 'ts-type-forge';\n\n/**\n * Namespace providing type guards and runtime-checked casts for the branded\n * length-constrained string types (`MinLengthString`, `MaxLengthString`,\n * `BoundedLengthString`, `FixedLengthString`).\n *\n * Lengths are measured in UTF-16 code units (the same unit as\n * `String.prototype.length`), so characters outside the Basic Multilingual\n * Plane (e.g. emoji) count as 2.\n */\nexport namespace Str {\n /**\n * Type guard that checks if a string has at least `minLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MinLengthString<MinLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MinLengthString<3>` is assignable to\n * `MinLengthString<1>` (= `NonEmptyString`).\n *\n * @example\n *\n * ```ts\n * const input: string = 'very-secret-password';\n *\n * assert.isTrue(Str.isMinLengthString(12, input));\n *\n * assert.isFalse(Str.isMinLengthString(12, 'short'));\n *\n * if (Str.isMinLengthString(12, input)) {\n * const nonEmpty: NonEmptyString = input; // OK (12 >= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n * }\n * ```\n *\n * @template MinLength - The minimum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param minLength - The minimum number of characters (inclusive).\n * @param s - The string to check.\n * @returns `true` if `s.length >= minLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MinLengthString<MinLength> & S`.\n */\n export const isMinLengthString = <\n MinLength extends SupportedLength,\n S extends string,\n >(\n minLength: MinLength,\n s: S,\n ): s is MinLengthString<MinLength> & S => s.length >= minLength;\n\n /**\n * Type guard that checks if a string has at most `maxLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MaxLengthString<MaxLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MaxLengthString<16>` is assignable to\n * `MaxLengthString<32>`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'noshiro';\n *\n * assert.isTrue(Str.isMaxLengthString(32, input));\n *\n * assert.isFalse(Str.isMaxLengthString(3, input));\n *\n * if (Str.isMaxLengthString(32, input)) {\n * const relaxed: MaxLengthString<64> = input; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n * }\n * ```\n *\n * @template MaxLength - The maximum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param maxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @returns `true` if `s.length <= maxLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MaxLengthString<MaxLength> & S`.\n */\n export const isMaxLengthString = <\n MaxLength extends SupportedLength,\n S extends string,\n >(\n maxLength: MaxLength,\n s: S,\n ): s is MaxLengthString<MaxLength> & S => s.length <= maxLength;\n\n /**\n * Type guard that checks if a string's length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `BoundedLengthString<MinLength, MaxLength>` while\n * preserving the original string type (e.g. literal types) via intersection.\n * - Since `BoundedLengthString` is the intersection of `MinLengthString` and\n * `MaxLengthString`, the narrowed value is assignable to both, and both\n * bounds can be weakened independently.\n *\n * @example\n *\n * ```ts\n * const input: string = 'user-12345678';\n *\n * assert.isTrue(Str.isBoundedLengthString(8, 16, input));\n *\n * assert.isFalse(Str.isBoundedLengthString(8, 16, 'user'));\n *\n * if (Str.isBoundedLengthString(8, 16, input)) {\n * const userId: BoundedLengthString<1, 255> = input; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(userId.length >= 8 && userId.length <= 16);\n * }\n * ```\n *\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @returns `true` if `minLength <= s.length && s.length <= maxLength`, `false`\n * otherwise. When `true`, TypeScript narrows `s` to\n * `BoundedLengthString<MinLength, MaxLength> & S`.\n */\n export const isBoundedLengthString = <\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n S extends string,\n >(\n minLength: MinLength,\n maxLength: MaxLength,\n s: S,\n ): s is BoundedLengthString<MinLength, MaxLength> & S =>\n s.length >= minLength && s.length <= maxLength;\n\n /**\n * Type guard that checks if a string has exactly `length` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `FixedLengthString<Length>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - Since `FixedLengthString<Length>` is defined as\n * `BoundedLengthString<Length, Length>`, the narrowed value is assignable to\n * any `MinLengthString<N>` with `N <= Length` and any `MaxLengthString<N>`\n * with `N >= Length`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'JP';\n *\n * assert.isTrue(Str.isFixedLengthString(2, input));\n *\n * assert.isFalse(Str.isFixedLengthString(3, input));\n *\n * if (Str.isFixedLengthString(2, input)) {\n * const atMost5: MaxLengthString<5> = input; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n * }\n * ```\n *\n * @template Length - The exact number of characters.\n * @template S - The input string type (literal types are preserved).\n * @param length - The exact number of characters.\n * @param s - The string to check.\n * @returns `true` if `s.length === length`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `FixedLengthString<Length> & S`.\n */\n export const isFixedLengthString = <\n Length extends SupportedLength,\n S extends string,\n >(\n length: Length,\n s: S,\n ): s is FixedLengthString<Length> & S => s.length === length;\n\n /**\n * Casts a string to `MinLengthString<MinLength>` after checking that it has\n * at least `minLength` characters.\n *\n * Use this instead of writing `s as unknown as MinLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const password = Str.asMinLengthString(12, 'very-secret-password');\n *\n * const nonEmpty: NonEmptyString = password; // OK (>= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n *\n * // curried version\n * const asPassword = Str.asMinLengthString(12);\n *\n * assert.strictEqual(asPassword('another-secret'), 'another-secret');\n *\n * assert.throws(() => Str.asMinLengthString(12, 'short')); // length 5 < 12\n * ```\n *\n * @template MinLength - The minimum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param minLength - The minimum number of characters (inclusive).\n * @param s - The string to cast.\n * @returns `s` typed as `MinLengthString<MinLength> & S`.\n * @throws {TypeError} If `s.length < minLength`.\n */\n export function asMinLengthString<\n MinLength extends SupportedLength,\n S extends string,\n >(minLength: MinLength, s: S): MinLengthString<MinLength> & S;\n\n // Curried version\n export function asMinLengthString<MinLength extends SupportedLength>(\n minLength: MinLength,\n ): <S extends string>(s: S) => MinLengthString<MinLength> & S;\n\n export function asMinLengthString(\n ...args:\n | readonly [minLength: SupportedLength, s: string]\n | readonly [minLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asMinLengthStringImpl(...args);\n\n case 1:\n return (s) => asMinLengthStringImpl(args[0], s);\n }\n }\n\n const asMinLengthStringImpl = (\n minLength: SupportedLength,\n s: string,\n ): string => {\n const actualLength = s.length;\n\n if (!isMinLengthString(minLength, s)) {\n throw new TypeError(\n `Expected a string of length >= ${minLength}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `MaxLengthString<MaxLength>` after checking that it has\n * at most `maxLength` characters.\n *\n * Use this instead of writing `s as unknown as MaxLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `maxLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userName = Str.asMaxLengthString(32, 'noshiro');\n *\n * const relaxed: MaxLengthString<64> = userName; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n *\n * // curried version\n * const asUserName = Str.asMaxLengthString(32);\n *\n * assert.strictEqual(asUserName('another-user'), 'another-user');\n *\n * assert.throws(() => Str.asMaxLengthString(3, 'noshiro')); // length 7 > 3\n * ```\n *\n * @template MaxLength - The maximum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param maxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @returns `s` typed as `MaxLengthString<MaxLength> & S`.\n * @throws {TypeError} If `s.length > maxLength`.\n */\n export function asMaxLengthString<\n MaxLength extends SupportedLength,\n S extends string,\n >(maxLength: MaxLength, s: S): MaxLengthString<MaxLength> & S;\n\n // Curried version\n export function asMaxLengthString<MaxLength extends SupportedLength>(\n maxLength: MaxLength,\n ): <S extends string>(s: S) => MaxLengthString<MaxLength> & S;\n\n export function asMaxLengthString(\n ...args:\n | readonly [maxLength: SupportedLength, s: string]\n | readonly [maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asMaxLengthStringImpl(...args);\n\n case 1:\n return (s) => asMaxLengthStringImpl(args[0], s);\n }\n }\n\n const asMaxLengthStringImpl = (\n maxLength: SupportedLength,\n s: string,\n ): string => {\n const actualLength = s.length;\n\n if (!isMaxLengthString(maxLength, s)) {\n throw new TypeError(\n `Expected a string of length <= ${maxLength}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `BoundedLengthString<MinLength, MaxLength>` after\n * checking that its length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * Use this instead of writing `s as unknown as BoundedLengthString<M, N>`:\n * the length is verified at runtime, and the original string type (e.g.\n * literal types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` and\n * `maxLength` returns a function that casts a string, which is convenient for\n * `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userId = Str.asBoundedLengthString(8, 16, 'user-12345678');\n *\n * const relaxed: BoundedLengthString<1, 255> = userId; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(relaxed.length >= 8 && relaxed.length <= 16);\n *\n * // curried version\n * const asUserId = Str.asBoundedLengthString(8, 16);\n *\n * assert.strictEqual(asUserId('user-87654321'), 'user-87654321');\n *\n * assert.throws(() => Str.asBoundedLengthString(8, 16, 'user')); // length 4 < 8\n * ```\n *\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @template S - The input string type (literal types are preserved).\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.\n * @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.\n */\n export function asBoundedLengthString<\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n S extends string,\n >(\n minLength: MinLength,\n maxLength: MaxLength,\n s: S,\n ): BoundedLengthString<MinLength, MaxLength> & S;\n\n // Curried version\n export function asBoundedLengthString<\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n minLength: MinLength,\n maxLength: MaxLength,\n ): <S extends string>(s: S) => BoundedLengthString<MinLength, MaxLength> & S;\n\n export function asBoundedLengthString(\n ...args:\n | readonly [\n minLength: SupportedLength,\n maxLength: SupportedLength,\n s: string,\n ]\n | readonly [minLength: SupportedLength, maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 3:\n return asBoundedLengthStringImpl(...args);\n\n case 2:\n return (s) => asBoundedLengthStringImpl(...args, s);\n }\n }\n\n const asBoundedLengthStringImpl = (\n minLength: SupportedLength,\n maxLength: SupportedLength,\n s: string,\n ): string => {\n const actualLength = s.length;\n\n if (!isBoundedLengthString(minLength, maxLength, s)) {\n throw new TypeError(\n `Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `FixedLengthString<Length>` after checking that it has\n * exactly `length` characters.\n *\n * Use this instead of writing `s as unknown as FixedLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `length` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const countryCode = Str.asFixedLengthString(2, 'JP');\n *\n * const atMost5: MaxLengthString<5> = countryCode; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n *\n * // curried version\n * const asCountryCode = Str.asFixedLengthString(2);\n *\n * assert.strictEqual(asCountryCode('US'), 'US');\n *\n * assert.throws(() => Str.asFixedLengthString(3, 'JP')); // length 2 !== 3\n * ```\n *\n * @template Length - The exact number of characters.\n * @template S - The input string type (literal types are preserved).\n * @param length - The exact number of characters.\n * @param s - The string to cast.\n * @returns `s` typed as `FixedLengthString<Length> & S`.\n * @throws {TypeError} If `s.length !== length`.\n */\n export function asFixedLengthString<\n Length extends SupportedLength,\n S extends string,\n >(length: Length, s: S): FixedLengthString<Length> & S;\n\n // Curried version\n export function asFixedLengthString<Length extends SupportedLength>(\n length: Length,\n ): <S extends string>(s: S) => FixedLengthString<Length> & S;\n\n export function asFixedLengthString(\n ...args:\n | readonly [length: SupportedLength, s: string]\n | readonly [length: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2:\n return asFixedLengthStringImpl(...args);\n\n case 1:\n return (s) => asFixedLengthStringImpl(args[0], s);\n }\n }\n\n const asFixedLengthStringImpl = (\n length: SupportedLength,\n s: string,\n ): string => {\n const actualLength = s.length;\n\n if (!isFixedLengthString(length, s)) {\n throw new TypeError(\n `Expected a string of length ${length}, got a string of length ${actualLength}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `NonEmptyString` after checking that it has at least one\n * character.\n *\n * `NonEmptyString` is an alias of `MinLengthString<1>`, so this is the\n * length-1 specialization of {@link asMinLengthString}. Use this instead of\n * writing `s as unknown as NonEmptyString`: the length is verified at\n * runtime, and the original string type (e.g. literal types) is preserved\n * via intersection.\n *\n * @example\n *\n * ```ts\n * const name = Str.asNonEmptyString('noshiro');\n *\n * const nonEmpty: NonEmptyString = name; // OK\n *\n * assert.isTrue(nonEmpty.length >= 1);\n *\n * assert.throws(() => Str.asNonEmptyString('')); // length 0 < 1\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @param s - The string to cast.\n * @returns `s` typed as `NonEmptyString & S`.\n * @throws {TypeError} If `s` is empty.\n */\n export const asNonEmptyString = <S extends string>(\n s: S,\n ): NonEmptyString & S => {\n if (!isMinLengthString(1, s)) {\n throw new TypeError('Expected a non-empty string, got an empty string');\n }\n\n return s;\n };\n}\n"],"names":["Str"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-data-forge",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@sindresorhus/is": "^8.1.0",
|
|
39
|
-
"ts-type-forge": "
|
|
39
|
+
"ts-type-forge": "^9.1.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@emotion/react": "11.14.0",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type BoolOr,
|
|
3
|
+
type FixedLengthArray,
|
|
3
4
|
type FixedLengthTuple,
|
|
4
5
|
type Index,
|
|
5
6
|
type IsUnion,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
type Seq,
|
|
17
18
|
type SmallUint,
|
|
18
19
|
type StructuralPrefixLength,
|
|
20
|
+
type SupportedLength,
|
|
19
21
|
} from 'ts-type-forge';
|
|
20
22
|
import { expectType } from '../../expect-type.mjs';
|
|
21
23
|
import { range as rangeIterator } from '../../iterator/index.mjs';
|
|
@@ -91,9 +93,11 @@ export const create = <N extends SizeType.ArgArr, const V>(
|
|
|
91
93
|
init: V,
|
|
92
94
|
): N extends StructuralPrefixLength
|
|
93
95
|
? FixedLengthTuple<N, V>
|
|
94
|
-
: N extends
|
|
95
|
-
?
|
|
96
|
-
:
|
|
96
|
+
: N extends SupportedLength
|
|
97
|
+
? FixedLengthArray<N, V>
|
|
98
|
+
: N extends SizeType.ArgArrPositive
|
|
99
|
+
? NonEmptyArray<V>
|
|
100
|
+
: readonly V[] =>
|
|
97
101
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
98
102
|
Array.from({ length: Math.max(0, len) }, () => init) as never;
|
|
99
103
|
|