ts-fortress 6.2.2 → 6.2.4
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/array-at-least-length.d.mts +2 -2
- package/dist/array/array-at-least-length.d.mts.map +1 -1
- package/dist/array/array-at-least-length.mjs.map +1 -1
- package/dist/array/array-of-length.d.mts +2 -2
- package/dist/array/array-of-length.d.mts.map +1 -1
- package/dist/array/array-of-length.mjs.map +1 -1
- package/dist/array/array.d.mts +2 -2
- package/dist/array/array.d.mts.map +1 -1
- package/dist/array/array.mjs.map +1 -1
- package/dist/array/non-empty-array.d.mts +2 -2
- package/dist/array/non-empty-array.d.mts.map +1 -1
- package/dist/array/non-empty-array.mjs.map +1 -1
- package/dist/array/tuple.d.mts +5 -5
- package/dist/array/tuple.d.mts.map +1 -1
- package/dist/array/tuple.mjs.map +1 -1
- package/dist/brand/brand.d.mts +1 -1
- package/dist/brand/brand.d.mts.map +1 -1
- package/dist/compose/intersection.d.mts +4 -4
- package/dist/compose/intersection.d.mts.map +1 -1
- package/dist/compose/intersection.mjs.map +1 -1
- package/dist/compose/merge-records.d.mts +3 -3
- package/dist/compose/merge-records.d.mts.map +1 -1
- package/dist/compose/merge-records.mjs.map +1 -1
- package/dist/compose/union.d.mts +2 -2
- package/dist/compose/union.d.mts.map +1 -1
- package/dist/compose/union.mjs.map +1 -1
- package/dist/enum/enum.d.mts +2 -2
- package/dist/enum/enum.d.mts.map +1 -1
- package/dist/enum/enum.mjs.map +1 -1
- package/dist/globals.d.mts +0 -2
- package/dist/other-types/map.d.mts +2 -2
- package/dist/other-types/map.d.mts.map +1 -1
- package/dist/other-types/map.mjs.map +1 -1
- package/dist/other-types/recursion.d.mts +2 -2
- package/dist/other-types/recursion.d.mts.map +1 -1
- package/dist/other-types/recursion.mjs +5 -7
- package/dist/other-types/recursion.mjs.map +1 -1
- package/dist/other-types/set.d.mts +2 -2
- package/dist/other-types/set.d.mts.map +1 -1
- package/dist/other-types/set.mjs.map +1 -1
- package/dist/predefined/brand/string/email.d.mts +2 -2
- package/dist/predefined/brand/string/email.d.mts.map +1 -1
- package/dist/predefined/brand/string/email.mjs.map +1 -1
- package/dist/predefined/brand/string/json-string.d.mts +2 -2
- package/dist/predefined/brand/string/json-string.d.mts.map +1 -1
- package/dist/predefined/brand/string/json-string.mjs.map +1 -1
- package/dist/predefined/brand/string/uuid.d.mts +2 -2
- package/dist/predefined/brand/string/uuid.d.mts.map +1 -1
- package/dist/predefined/brand/string/uuid.mjs.map +1 -1
- package/dist/primitives/bigint.d.mts +10 -10
- package/dist/primitives/bigint.d.mts.map +1 -1
- package/dist/primitives/bigint.mjs.map +1 -1
- package/dist/primitives/number.d.mts +10 -10
- package/dist/primitives/number.d.mts.map +1 -1
- package/dist/primitives/number.mjs.map +1 -1
- package/dist/primitives/string.d.mts +20 -20
- package/dist/primitives/string.d.mts.map +1 -1
- package/dist/primitives/string.mjs.map +1 -1
- package/dist/record/key-value-record.d.mts +2 -2
- package/dist/record/key-value-record.d.mts.map +1 -1
- package/dist/record/key-value-record.mjs.map +1 -1
- package/dist/record/keyof.d.mts +2 -2
- package/dist/record/keyof.d.mts.map +1 -1
- package/dist/record/keyof.mjs.map +1 -1
- package/dist/record/omit.d.mts +2 -2
- package/dist/record/omit.d.mts.map +1 -1
- package/dist/record/omit.mjs.map +1 -1
- package/dist/record/partial.d.mts +8 -8
- package/dist/record/partial.d.mts.map +1 -1
- package/dist/record/partial.mjs.map +1 -1
- package/dist/record/pick.d.mts +2 -2
- package/dist/record/pick.d.mts.map +1 -1
- package/dist/record/pick.mjs.map +1 -1
- package/dist/record/record.d.mts +4 -4
- package/dist/record/record.d.mts.map +1 -1
- package/dist/record/record.mjs.map +1 -1
- package/dist/record/required.d.mts +8 -8
- package/dist/record/required.d.mts.map +1 -1
- package/dist/record/required.mjs.map +1 -1
- package/dist/record/valueof.d.mts +2 -2
- package/dist/record/valueof.d.mts.map +1 -1
- package/dist/record/valueof.mjs.map +1 -1
- package/dist/type.d.mts +4 -4
- package/dist/type.d.mts.map +1 -1
- package/package.json +26 -19
- package/src/array/array-at-least-length.mts +6 -4
- package/src/array/array-of-length.mts +6 -4
- package/src/array/array.mts +6 -4
- package/src/array/non-empty-array.mts +6 -4
- package/src/array/tuple.mts +8 -6
- package/src/brand/brand.mts +1 -1
- package/src/compose/intersection.mts +76 -59
- package/src/compose/merge-records.mts +74 -59
- package/src/compose/union-literal-array.test.mts +1 -1
- package/src/compose/union-nested-record.test.mts +10 -8
- package/src/compose/union-records.test.mts +10 -8
- package/src/compose/union.mts +18 -8
- package/src/enum/enum.mts +6 -4
- package/src/globals.d.mts +0 -2
- package/src/other-types/map.mts +5 -3
- package/src/other-types/recursion.mts +10 -10
- package/src/other-types/recursion.test.mts +1 -1
- package/src/other-types/set.mts +5 -3
- package/src/predefined/brand/string/email.mts +5 -3
- package/src/predefined/brand/string/json-string.mts +5 -3
- package/src/predefined/brand/string/uuid.mts +10 -8
- package/src/primitives/bigint.mts +24 -30
- package/src/primitives/number.mts +24 -30
- package/src/primitives/string.mts +53 -58
- package/src/record/key-value-record.mts +5 -3
- package/src/record/keyof.mts +17 -9
- package/src/record/omit.mts +19 -14
- package/src/record/partial.mts +25 -18
- package/src/record/pick.mts +19 -14
- package/src/record/record.mts +28 -24
- package/src/record/required.mts +27 -26
- package/src/record/valueof.mts +9 -7
- package/src/type.mts +9 -15
|
@@ -23,14 +23,16 @@ describe('union - records only', () => {
|
|
|
23
23
|
|
|
24
24
|
expectType<
|
|
25
25
|
TargetType,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
Readonly<
|
|
27
|
+
| {
|
|
28
|
+
kind: string;
|
|
29
|
+
value: number;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
type: string;
|
|
33
|
+
data: string;
|
|
34
|
+
}
|
|
35
|
+
>
|
|
34
36
|
>('=');
|
|
35
37
|
|
|
36
38
|
expectType<typeof targetType.defaultValue, TargetType>('=');
|
package/src/compose/union.mts
CHANGED
|
@@ -10,10 +10,12 @@ import {
|
|
|
10
10
|
|
|
11
11
|
export const union = <const Types extends NonEmptyArray<Type<unknown>>>(
|
|
12
12
|
types: Types,
|
|
13
|
-
options?:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
options?: Partial<
|
|
14
|
+
Readonly<{
|
|
15
|
+
typeName: string;
|
|
16
|
+
defaultType: UnionType<Types>;
|
|
17
|
+
}>
|
|
18
|
+
>,
|
|
17
19
|
): UnionType<Types> => {
|
|
18
20
|
type T = UnionTypeValue<Types>;
|
|
19
21
|
|
|
@@ -70,11 +72,19 @@ namespace TsFortressInternal {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
expectType<
|
|
73
|
-
UnionType<
|
|
74
|
-
|
|
75
|
+
UnionType<
|
|
76
|
+
readonly [Type<Readonly<{ a: 0; b: 0 }>>, Type<Readonly<{ b: 0; c: 0 }>>]
|
|
77
|
+
>,
|
|
78
|
+
Type<Readonly<{ a: 0; b: 0 } | { b: 0; c: 0 }>>
|
|
75
79
|
>('=');
|
|
76
80
|
|
|
77
81
|
expectType<
|
|
78
|
-
UnionType<
|
|
79
|
-
|
|
82
|
+
UnionType<
|
|
83
|
+
readonly [
|
|
84
|
+
Type<Readonly<{ a: 0; b: 0 }>>,
|
|
85
|
+
Type<Readonly<{ b: 0; c: 0 }>>,
|
|
86
|
+
Type<Readonly<{ e: 0; f: 0 }>>,
|
|
87
|
+
]
|
|
88
|
+
>,
|
|
89
|
+
Type<Readonly<{ a: 0; b: 0 } | { b: 0; c: 0 } | { e: 0; f: 0 }>>
|
|
80
90
|
>('=');
|
package/src/enum/enum.mts
CHANGED
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
|
|
10
10
|
export const enumType = <const Values extends NonEmptyArray<Primitive>>(
|
|
11
11
|
values: Values,
|
|
12
|
-
options?:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
options?: Partial<
|
|
13
|
+
Readonly<{
|
|
14
|
+
typeName: string;
|
|
15
|
+
defaultValue: ArrayElement<Values>;
|
|
16
|
+
}>
|
|
17
|
+
>,
|
|
16
18
|
): Type<ArrayElement<Values>> => {
|
|
17
19
|
type T = ArrayElement<Values>;
|
|
18
20
|
|
package/src/globals.d.mts
CHANGED
package/src/other-types/map.mts
CHANGED
|
@@ -20,9 +20,11 @@ type MapResultType<
|
|
|
20
20
|
export const MapType = <K extends Type<unknown>, V extends Type<unknown>>(
|
|
21
21
|
keyType: K,
|
|
22
22
|
valueType: V,
|
|
23
|
-
options?:
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
options?: Partial<
|
|
24
|
+
Readonly<{
|
|
25
|
+
typeName: string;
|
|
26
|
+
}>
|
|
27
|
+
>,
|
|
26
28
|
): Type<MapResultType<K, V>> => {
|
|
27
29
|
type M = MapResultType<K, V>;
|
|
28
30
|
|
|
@@ -4,11 +4,13 @@ import { createAssertFn, createCastFn, createIsFn } from '../utils/index.mjs';
|
|
|
4
4
|
export const recursion = <A,>(
|
|
5
5
|
typeName: string,
|
|
6
6
|
definition: () => Type<A>,
|
|
7
|
-
options?:
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
options?: Partial<
|
|
8
|
+
Readonly<{
|
|
9
|
+
defaultValue: A;
|
|
10
|
+
}>
|
|
11
|
+
>,
|
|
10
12
|
): Type<A> => {
|
|
11
|
-
const
|
|
13
|
+
const mut_cache: {
|
|
12
14
|
innerType: Type<A> | undefined;
|
|
13
15
|
computedDefaultValue: A | undefined;
|
|
14
16
|
} = {
|
|
@@ -17,10 +19,9 @@ export const recursion = <A,>(
|
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
const getInnerType = (): Type<A> => {
|
|
20
|
-
|
|
21
|
-
cache.innerType ??= definition();
|
|
22
|
+
mut_cache.innerType ??= definition();
|
|
22
23
|
|
|
23
|
-
return
|
|
24
|
+
return mut_cache.innerType;
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
const validate: Type<A>['validate'] = (a) => getInnerType().validate(a);
|
|
@@ -36,10 +37,9 @@ export const recursion = <A,>(
|
|
|
36
37
|
return options.defaultValue;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
cache.computedDefaultValue ??= getInnerType().defaultValue;
|
|
40
|
+
mut_cache.computedDefaultValue ??= getInnerType().defaultValue;
|
|
41
41
|
|
|
42
|
-
return
|
|
42
|
+
return mut_cache.computedDefaultValue;
|
|
43
43
|
},
|
|
44
44
|
fill,
|
|
45
45
|
validate,
|
|
@@ -183,7 +183,7 @@ describe('recursive', () => {
|
|
|
183
183
|
|
|
184
184
|
// Test other recursive structures
|
|
185
185
|
test('Linked list structure', () => {
|
|
186
|
-
type LinkedList<T> = { value: T; next: LinkedList<T> | null }
|
|
186
|
+
type LinkedList<T> = Readonly<{ value: T; next: LinkedList<T> | null }>;
|
|
187
187
|
|
|
188
188
|
const LinkedListNumber: Type<LinkedList<number>> = recursion(
|
|
189
189
|
'LinkedList<number>',
|
package/src/other-types/set.mts
CHANGED
|
@@ -15,9 +15,11 @@ type SetResultType<T extends Type<unknown>> = ReadonlySet<TypeOf<T>>;
|
|
|
15
15
|
|
|
16
16
|
export const SetType = <T extends Type<unknown>>(
|
|
17
17
|
elementType: T,
|
|
18
|
-
options?:
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
options?: Partial<
|
|
19
|
+
Readonly<{
|
|
20
|
+
typeName: string;
|
|
21
|
+
}>
|
|
22
|
+
>,
|
|
21
23
|
): Type<SetResultType<T>> => {
|
|
22
24
|
type S = SetResultType<T>;
|
|
23
25
|
|
|
@@ -5,9 +5,11 @@ import { type Type } from '../../../type.mjs';
|
|
|
5
5
|
* @link https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
|
|
6
6
|
*/
|
|
7
7
|
export const email = (
|
|
8
|
-
options?:
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
options?: Partial<
|
|
9
|
+
Readonly<{
|
|
10
|
+
defaultValue: string;
|
|
11
|
+
}>
|
|
12
|
+
>,
|
|
11
13
|
): Type<Email> =>
|
|
12
14
|
brandedString({
|
|
13
15
|
is: (s): s is Email => regexpEmailAddress.test(s),
|
|
@@ -6,9 +6,11 @@ import { type Type } from '../../../type.mjs';
|
|
|
6
6
|
* @link https://github.com/validatorjs/validator.js/tree/v13.1.17?tab=readme-ov-file#validators
|
|
7
7
|
*/
|
|
8
8
|
export const jsonString = (
|
|
9
|
-
options?:
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
options?: Partial<
|
|
10
|
+
Readonly<{
|
|
11
|
+
defaultValue: string;
|
|
12
|
+
}>
|
|
13
|
+
>,
|
|
12
14
|
): Type<JsonString> =>
|
|
13
15
|
brandedString({
|
|
14
16
|
is: isJsonString,
|
|
@@ -64,15 +64,17 @@ export const uuidV7 = (defaultValue?: string): Type<Uuid7> =>
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
type UuidValidatorOption<V extends UuidVersion | UuidVersionAdditionalOption> =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
Partial<
|
|
68
|
+
Readonly<{
|
|
69
|
+
/**
|
|
70
|
+
* @param version One of 1-8, 'nil', 'max', 'all' or 'loose'. The 'loose' option checks if the string is a UUID-like string with hexadecimal values, ignoring RFC9562.
|
|
71
|
+
*/
|
|
72
|
+
version: V;
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
typeName: string;
|
|
75
|
+
defaultValue: string;
|
|
76
|
+
}>
|
|
77
|
+
>;
|
|
76
78
|
|
|
77
79
|
const nilUuid = '00000000-0000-0000-0000-000000000000' satisfies UuidBaseString;
|
|
78
80
|
|
|
@@ -126,20 +126,22 @@ export function bigint<C extends Constraints>(
|
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
type Constraints =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
type Constraints = Partial<
|
|
130
|
+
Readonly<{
|
|
131
|
+
gt: bigint;
|
|
132
|
+
gte: bigint;
|
|
133
|
+
min: bigint;
|
|
134
|
+
lt: bigint;
|
|
135
|
+
lte: bigint;
|
|
136
|
+
max: bigint;
|
|
137
|
+
negative: boolean;
|
|
138
|
+
nonNegative: boolean;
|
|
139
|
+
positive: boolean;
|
|
140
|
+
nonPositive: boolean;
|
|
141
|
+
multipleOf: bigint;
|
|
142
|
+
step: bigint;
|
|
143
|
+
}>
|
|
144
|
+
>;
|
|
143
145
|
|
|
144
146
|
type DefaultValueType<
|
|
145
147
|
B extends bigint,
|
|
@@ -149,25 +151,17 @@ type DefaultValueType<
|
|
|
149
151
|
DefaultValueWhenPositiveIsOn<B, R> &
|
|
150
152
|
DefaultValueWhenNonPositiveIsOn<B, R>;
|
|
151
153
|
|
|
152
|
-
type DefaultValueWhenNegativeIsOn<
|
|
153
|
-
|
|
154
|
-
R extends Constraints,
|
|
155
|
-
> = R extends { negative: true } ? NegativeBigint<B> : bigint;
|
|
154
|
+
type DefaultValueWhenNegativeIsOn<B extends bigint, R extends Constraints> =
|
|
155
|
+
R extends Readonly<{ negative: true }> ? NegativeBigint<B> : bigint;
|
|
156
156
|
|
|
157
|
-
type DefaultValueWhenNonNegativeIsOn<
|
|
158
|
-
|
|
159
|
-
R extends Constraints,
|
|
160
|
-
> = R extends { nonNegative: true } ? NonNegativeBigint<B> : bigint;
|
|
157
|
+
type DefaultValueWhenNonNegativeIsOn<B extends bigint, R extends Constraints> =
|
|
158
|
+
R extends Readonly<{ nonNegative: true }> ? NonNegativeBigint<B> : bigint;
|
|
161
159
|
|
|
162
|
-
type DefaultValueWhenPositiveIsOn<
|
|
163
|
-
|
|
164
|
-
R extends Constraints,
|
|
165
|
-
> = R extends { positive: true } ? PositiveBigint<B> : bigint;
|
|
160
|
+
type DefaultValueWhenPositiveIsOn<B extends bigint, R extends Constraints> =
|
|
161
|
+
R extends Readonly<{ positive: true }> ? PositiveBigint<B> : bigint;
|
|
166
162
|
|
|
167
|
-
type DefaultValueWhenNonPositiveIsOn<
|
|
168
|
-
|
|
169
|
-
R extends Constraints,
|
|
170
|
-
> = R extends { nonPositive: true } ? NonPositiveBigint<B> : bigint;
|
|
163
|
+
type DefaultValueWhenNonPositiveIsOn<B extends bigint, R extends Constraints> =
|
|
164
|
+
R extends Readonly<{ nonPositive: true }> ? NonPositiveBigint<B> : bigint;
|
|
171
165
|
|
|
172
166
|
type NegativeBigint<B extends bigint> = bigint extends B
|
|
173
167
|
? bigint
|
|
@@ -109,20 +109,22 @@ export function number<C extends Constraints>(
|
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
type Constraints =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
112
|
+
type Constraints = Partial<
|
|
113
|
+
Readonly<{
|
|
114
|
+
gt: number;
|
|
115
|
+
gte: number;
|
|
116
|
+
min: number;
|
|
117
|
+
lt: number;
|
|
118
|
+
lte: number;
|
|
119
|
+
max: number;
|
|
120
|
+
negative: boolean;
|
|
121
|
+
nonNegative: boolean;
|
|
122
|
+
positive: boolean;
|
|
123
|
+
nonPositive: boolean;
|
|
124
|
+
multipleOf: number;
|
|
125
|
+
step: number;
|
|
126
|
+
}>
|
|
127
|
+
>;
|
|
126
128
|
|
|
127
129
|
type DefaultValueType<
|
|
128
130
|
N extends number,
|
|
@@ -132,25 +134,17 @@ type DefaultValueType<
|
|
|
132
134
|
DefaultValueWhenPositiveIsOn<N, R> &
|
|
133
135
|
DefaultValueWhenNonPositiveIsOn<N, R>;
|
|
134
136
|
|
|
135
|
-
type DefaultValueWhenNegativeIsOn<
|
|
136
|
-
|
|
137
|
-
R extends Constraints,
|
|
138
|
-
> = R extends { negative: true } ? NegativeNumber<N> : number;
|
|
137
|
+
type DefaultValueWhenNegativeIsOn<N extends number, R extends Constraints> =
|
|
138
|
+
R extends Readonly<{ negative: true }> ? NegativeNumber<N> : number;
|
|
139
139
|
|
|
140
|
-
type DefaultValueWhenNonNegativeIsOn<
|
|
141
|
-
|
|
142
|
-
R extends Constraints,
|
|
143
|
-
> = R extends { nonNegative: true } ? NonNegativeNumber<N> : number;
|
|
140
|
+
type DefaultValueWhenNonNegativeIsOn<N extends number, R extends Constraints> =
|
|
141
|
+
R extends Readonly<{ nonNegative: true }> ? NonNegativeNumber<N> : number;
|
|
144
142
|
|
|
145
|
-
type DefaultValueWhenPositiveIsOn<
|
|
146
|
-
|
|
147
|
-
R extends Constraints,
|
|
148
|
-
> = R extends { positive: true } ? PositiveNumber<N> : number;
|
|
143
|
+
type DefaultValueWhenPositiveIsOn<N extends number, R extends Constraints> =
|
|
144
|
+
R extends Readonly<{ positive: true }> ? PositiveNumber<N> : number;
|
|
149
145
|
|
|
150
|
-
type DefaultValueWhenNonPositiveIsOn<
|
|
151
|
-
|
|
152
|
-
R extends Constraints,
|
|
153
|
-
> = R extends { nonPositive: true } ? NonPositiveNumber<N> : number;
|
|
146
|
+
type DefaultValueWhenNonPositiveIsOn<N extends number, R extends Constraints> =
|
|
147
|
+
R extends Readonly<{ nonPositive: true }> ? NonPositiveNumber<N> : number;
|
|
154
148
|
|
|
155
149
|
type NegativeNumber<N extends number> = number extends N
|
|
156
150
|
? number
|
|
@@ -112,17 +112,19 @@ export function string<C extends Constraints>(
|
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
type Constraints =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
115
|
+
type Constraints = Partial<
|
|
116
|
+
Readonly<{
|
|
117
|
+
startsWith: string;
|
|
118
|
+
endsWith: string;
|
|
119
|
+
includes: string;
|
|
120
|
+
uppercase: boolean;
|
|
121
|
+
lowercase: boolean;
|
|
122
|
+
nonempty: boolean;
|
|
123
|
+
minLength: number;
|
|
124
|
+
maxLength: number;
|
|
125
|
+
regex: DeepReadonly<RegExp>;
|
|
126
|
+
}>
|
|
127
|
+
>;
|
|
126
128
|
|
|
127
129
|
type DefaultValueType<
|
|
128
130
|
S extends string,
|
|
@@ -141,56 +143,49 @@ type ConstraintsResultType<R extends Constraints> =
|
|
|
141
143
|
DefaultValueWhenEndsWithIsOn<R> &
|
|
142
144
|
DefaultValueWhenIncludesIsOn<R>;
|
|
143
145
|
|
|
144
|
-
type DefaultValueWhenStartsWithIsOn<R extends Constraints> =
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
R extends
|
|
170
|
-
> = R extends { lowercase: true } ? CastLowercase<S> : string;
|
|
146
|
+
type DefaultValueWhenStartsWithIsOn<R extends Constraints> =
|
|
147
|
+
R extends Readonly<{
|
|
148
|
+
startsWith: infer S extends string;
|
|
149
|
+
}>
|
|
150
|
+
? `${S}${string}`
|
|
151
|
+
: string;
|
|
152
|
+
|
|
153
|
+
type DefaultValueWhenEndsWithIsOn<R extends Constraints> =
|
|
154
|
+
R extends Readonly<{
|
|
155
|
+
endsWith: infer E extends string;
|
|
156
|
+
}>
|
|
157
|
+
? `${string}${E}`
|
|
158
|
+
: string;
|
|
159
|
+
|
|
160
|
+
type DefaultValueWhenIncludesIsOn<R extends Constraints> =
|
|
161
|
+
R extends Readonly<{
|
|
162
|
+
includes: infer M extends string;
|
|
163
|
+
}>
|
|
164
|
+
? `${string}${M}${string}`
|
|
165
|
+
: string;
|
|
166
|
+
|
|
167
|
+
type DefaultValueWhenUppercaseIsOn<S extends string, R extends Constraints> =
|
|
168
|
+
R extends Readonly<{ uppercase: true }> ? CastUppercase<S> : string;
|
|
169
|
+
|
|
170
|
+
type DefaultValueWhenLowercaseIsOn<S extends string, R extends Constraints> =
|
|
171
|
+
R extends Readonly<{ lowercase: true }> ? CastLowercase<S> : string;
|
|
171
172
|
|
|
172
173
|
type CastLowercase<S extends string> = S extends Lowercase<S> ? S : never;
|
|
173
174
|
|
|
174
175
|
type CastUppercase<S extends string> = S extends Uppercase<S> ? S : never;
|
|
175
176
|
|
|
176
|
-
type DefaultValueWhenNonemptyIsOn<
|
|
177
|
-
|
|
178
|
-
R extends Constraints,
|
|
179
|
-
> = R extends { nonempty: true } ? NonEmptyString<S> : string;
|
|
177
|
+
type DefaultValueWhenNonemptyIsOn<S extends string, R extends Constraints> =
|
|
178
|
+
R extends Readonly<{ nonempty: true }> ? NonEmptyString<S> : string;
|
|
180
179
|
|
|
181
|
-
type DefaultValueWhenMinLengthIsOn<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
? StringWithMinLength<S, M>
|
|
186
|
-
: string;
|
|
180
|
+
type DefaultValueWhenMinLengthIsOn<S extends string, R extends Constraints> =
|
|
181
|
+
R extends Readonly<{ minLength: infer M extends number }>
|
|
182
|
+
? StringWithMinLength<S, M>
|
|
183
|
+
: string;
|
|
187
184
|
|
|
188
|
-
type DefaultValueWhenMaxLengthIsOn<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
? StringWithMaxLength<S, M>
|
|
193
|
-
: string;
|
|
185
|
+
type DefaultValueWhenMaxLengthIsOn<S extends string, R extends Constraints> =
|
|
186
|
+
R extends Readonly<{ maxLength: infer M extends number }>
|
|
187
|
+
? StringWithMaxLength<S, M>
|
|
188
|
+
: string;
|
|
194
189
|
|
|
195
190
|
type NonEmptyString<S extends string> = string extends S
|
|
196
191
|
? string
|
|
@@ -207,7 +202,7 @@ type StringWithMaxLength<S extends string, N extends number> =
|
|
|
207
202
|
type HasLengthAtLeast<
|
|
208
203
|
S extends string,
|
|
209
204
|
N extends number,
|
|
210
|
-
Acc extends unknown[] = [],
|
|
205
|
+
Acc extends readonly unknown[] = readonly [],
|
|
211
206
|
> = string extends S
|
|
212
207
|
? true
|
|
213
208
|
: IsNegative<N> extends true
|
|
@@ -217,13 +212,13 @@ type HasLengthAtLeast<
|
|
|
217
212
|
: S extends ''
|
|
218
213
|
? false
|
|
219
214
|
: S extends `${infer _}${infer Rest}`
|
|
220
|
-
? HasLengthAtLeast<Rest, N, [...Acc, unknown]>
|
|
215
|
+
? HasLengthAtLeast<Rest, N, readonly [...Acc, unknown]>
|
|
221
216
|
: false;
|
|
222
217
|
|
|
223
218
|
type HasLengthAtMost<
|
|
224
219
|
S extends string,
|
|
225
220
|
N extends number,
|
|
226
|
-
Acc extends unknown[] = [],
|
|
221
|
+
Acc extends readonly unknown[] = readonly [],
|
|
227
222
|
> = string extends S
|
|
228
223
|
? true
|
|
229
224
|
: IsNegative<N> extends true
|
|
@@ -233,7 +228,7 @@ type HasLengthAtMost<
|
|
|
233
228
|
: Acc['length'] extends N
|
|
234
229
|
? false
|
|
235
230
|
: S extends `${infer _}${infer Rest}`
|
|
236
|
-
? HasLengthAtMost<Rest, N, [...Acc, unknown]>
|
|
231
|
+
? HasLengthAtMost<Rest, N, readonly [...Acc, unknown]>
|
|
237
232
|
: false;
|
|
238
233
|
|
|
239
234
|
type IsNegative<N extends number> = `${N}` extends `-${string}` ? true : false;
|
|
@@ -17,9 +17,11 @@ type RecordResultType<
|
|
|
17
17
|
export const keyValueRecord = <K extends Type<string>, V extends Type<unknown>>(
|
|
18
18
|
keyType: K,
|
|
19
19
|
valueType: V,
|
|
20
|
-
options?:
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
options?: Partial<
|
|
21
|
+
Readonly<{
|
|
22
|
+
typeName: string;
|
|
23
|
+
}>
|
|
24
|
+
>,
|
|
23
25
|
): Type<RecordResultType<K, V>> => {
|
|
24
26
|
type T = RecordResultType<K, V>;
|
|
25
27
|
|
package/src/record/keyof.mts
CHANGED
|
@@ -5,9 +5,11 @@ import { type RecordType, type Type } from '../type.mjs';
|
|
|
5
5
|
|
|
6
6
|
export const keyof = <const R extends ReadonlyRecord<string, Type<unknown>>>(
|
|
7
7
|
recordType: RecordType<R>,
|
|
8
|
-
options?:
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
options?: Partial<
|
|
9
|
+
Readonly<{
|
|
10
|
+
typeName: string;
|
|
11
|
+
}>
|
|
12
|
+
>,
|
|
11
13
|
): KeyofType<R> =>
|
|
12
14
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
13
15
|
pipe(getKeys(recordType)).map((keys) =>
|
|
@@ -22,7 +24,11 @@ const getKeys = <const R extends ReadonlyRecord<string, Type<unknown>>>(
|
|
|
22
24
|
recordType: RecordType<R>,
|
|
23
25
|
): readonly ToString<keyof R>[] =>
|
|
24
26
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
25
|
-
Object.keys(
|
|
27
|
+
Object.keys(
|
|
28
|
+
recordType.shape,
|
|
29
|
+
) satisfies readonly string[] as readonly string[] as readonly ToString<
|
|
30
|
+
keyof R
|
|
31
|
+
>[];
|
|
26
32
|
|
|
27
33
|
type KeyofTypeSub<R extends ReadonlyRecord<string, Type<unknown>>> = Type<
|
|
28
34
|
ToString<keyof R>
|
|
@@ -34,24 +40,26 @@ type KeyofType<R extends ReadonlyRecord<string, Type<unknown>>> =
|
|
|
34
40
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
35
41
|
expectType<keyof {}, never>('=');
|
|
36
42
|
|
|
37
|
-
expectType<ToString<keyof { 1: 1; 2: 2; 3: 3 }
|
|
43
|
+
expectType<ToString<keyof Readonly<{ 1: 1; 2: 2; 3: 3 }>>, '1' | '2' | '3'>(
|
|
44
|
+
'=',
|
|
45
|
+
);
|
|
38
46
|
|
|
39
47
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
40
48
|
expectType<KeyofType<{}>, Type<undefined>>('=');
|
|
41
49
|
|
|
42
50
|
expectType<
|
|
43
|
-
KeyofType<{ a: Type<0>; b: Type<1>; c: Type<2> }
|
|
51
|
+
KeyofType<Readonly<{ a: Type<0>; b: Type<1>; c: Type<2> }>>,
|
|
44
52
|
Type<'a' | 'b' | 'c'>
|
|
45
53
|
>('=');
|
|
46
54
|
|
|
47
55
|
expectType<
|
|
48
|
-
KeyofType<{ x: Type<string>; y: Type<number>; z: Type<boolean> }
|
|
56
|
+
KeyofType<Readonly<{ x: Type<string>; y: Type<number>; z: Type<boolean> }>>,
|
|
49
57
|
Type<'x' | 'y' | 'z'>
|
|
50
58
|
>('=');
|
|
51
59
|
|
|
52
60
|
expectType<
|
|
53
|
-
KeyofType<{ same: Type<string>; value: Type<string> }
|
|
61
|
+
KeyofType<Readonly<{ same: Type<string>; value: Type<string> }>>,
|
|
54
62
|
Type<'same' | 'value'>
|
|
55
63
|
>('=');
|
|
56
64
|
|
|
57
|
-
expectType<KeyofType<{ never: Type<never> }
|
|
65
|
+
expectType<KeyofType<Readonly<{ never: Type<never> }>>, Type<'never'>>('=');
|