@depup/type-fest 5.5.0-depup.0 → 5.10.0-depup.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 +2 -2
- package/changes.json +1 -1
- package/index.d.ts +17 -8
- package/package.json +9 -6
- package/readme.md +75 -61
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +9 -5
- package/source/all-union-fields.d.ts +18 -18
- package/source/and.d.ts +1 -1
- package/source/array-reverse.d.ts +17 -15
- package/source/array-splice.d.ts +24 -24
- package/source/array-tail.d.ts +7 -7
- package/source/camel-case.d.ts +38 -5
- package/source/camel-cased-properties-deep.d.ts +11 -4
- package/source/camel-cased-properties.d.ts +5 -1
- package/source/conditional-keys.d.ts +1 -1
- package/source/delimiter-case.d.ts +11 -9
- package/source/delimiter-cased-properties-deep.d.ts +8 -1
- package/source/delimiter-cased-properties.d.ts +5 -1
- package/source/empty-object.d.ts +1 -1
- package/source/entries.d.ts +1 -1
- package/source/entry.d.ts +1 -1
- package/source/exclude-exactly.d.ts +11 -11
- package/source/exclude-rest-element.d.ts +4 -4
- package/source/exclusify-union.d.ts +4 -4
- package/source/extends-strict.d.ts +129 -22
- package/source/extract-exactly.d.ts +56 -0
- package/source/get.d.ts +1 -1
- package/source/greater-than.d.ts +3 -2
- package/source/has-optional-keys.d.ts +1 -1
- package/source/has-readonly-keys.d.ts +1 -1
- package/source/has-required-keys.d.ts +1 -1
- package/source/has-writable-keys.d.ts +1 -1
- package/source/int-closed-range.d.ts +5 -4
- package/source/int-range.d.ts +57 -12
- package/source/internal/array.d.ts +22 -21
- package/source/internal/keys.d.ts +9 -9
- package/source/internal/numeric.d.ts +19 -65
- package/source/internal/object.d.ts +44 -6
- package/source/internal/string.d.ts +1 -76
- package/source/internal/tuple.d.ts +2 -2
- package/source/internal/type.d.ts +16 -10
- package/source/is-boolean-literal.d.ts +39 -0
- package/source/is-integer.d.ts +8 -8
- package/source/is-literal.d.ts +43 -267
- package/source/is-numeric-literal.d.ts +50 -0
- package/source/is-string-literal.d.ts +72 -0
- package/source/is-symbol-literal.d.ts +39 -0
- package/source/is-tuple.d.ts +3 -3
- package/source/is-union.d.ts +12 -12
- package/source/iterable-element.d.ts +5 -5
- package/source/jsonify.d.ts +5 -9
- package/source/kebab-case.d.ts +1 -0
- package/source/kebab-cased-properties-deep.d.ts +7 -0
- package/source/kebab-cased-properties.d.ts +5 -1
- package/source/keys-of-union.d.ts +2 -2
- package/source/last-array-element.d.ts +66 -13
- package/source/less-than-or-equal.d.ts +1 -1
- package/source/literal-to-primitive.d.ts +1 -1
- package/source/literal-union.d.ts +1 -1
- package/source/merge-deep.d.ts +3 -3
- package/source/merge-exclusive.d.ts +3 -3
- package/source/multidimensional-array.d.ts +1 -1
- package/source/multidimensional-readonly-array.d.ts +1 -1
- package/source/non-nullable-deep.d.ts +102 -0
- package/source/numeric.d.ts +3 -3
- package/source/object-merge.d.ts +21 -16
- package/source/omit-deep.d.ts +22 -22
- package/source/or.d.ts +1 -1
- package/source/package-json.d.ts +7 -7
- package/source/partial-deep.d.ts +3 -1
- package/source/pascal-case.d.ts +1 -0
- package/source/pascal-cased-properties-deep.d.ts +7 -0
- package/source/pascal-cased-properties.d.ts +5 -1
- package/source/pick-deep.d.ts +2 -0
- package/source/readonly-deep.d.ts +5 -3
- package/source/remove-prefix.d.ts +16 -34
- package/source/remove-suffix.d.ts +114 -0
- package/source/rename-keys.d.ts +163 -0
- package/source/replace.d.ts +2 -2
- package/source/require-all-or-none.d.ts +5 -5
- package/source/require-at-least-one.d.ts +9 -11
- package/source/require-exactly-one.d.ts +7 -7
- package/source/require-one-or-none.d.ts +5 -5
- package/source/required-deep.d.ts +3 -1
- package/source/schema.d.ts +16 -8
- package/source/screaming-snake-case.d.ts +1 -0
- package/source/set-non-nullable-deep.d.ts +8 -4
- package/source/set-non-nullable.d.ts +1 -1
- package/source/set-optional.d.ts +5 -5
- package/source/set-readonly.d.ts +3 -3
- package/source/set-required-deep.d.ts +3 -2
- package/source/set-required.d.ts +13 -12
- package/source/shared-union-fields-deep.d.ts +6 -4
- package/source/shared-union-fields.d.ts +9 -9
- package/source/snake-case.d.ts +1 -0
- package/source/snake-cased-properties-deep.d.ts +7 -0
- package/source/snake-cased-properties.d.ts +5 -1
- package/source/some-extend.d.ts +9 -5
- package/source/split-on-rest-element.d.ts +20 -17
- package/source/split.d.ts +22 -11
- package/source/string-length.d.ts +38 -0
- package/source/string-repeat.d.ts +48 -21
- package/source/string-slice.d.ts +1 -1
- package/source/string-to-array.d.ts +97 -0
- package/source/string-to-number.d.ts +67 -0
- package/source/subtract.d.ts +4 -3
- package/source/sum.d.ts +5 -4
- package/source/tagged.d.ts +3 -5
- package/source/tsconfig-json.d.ts +40 -8
- package/source/tuple-of.d.ts +42 -8
- package/source/typed-array.d.ts +6 -0
- package/source/union-length.d.ts +27 -0
- package/source/union-max.d.ts +56 -0
- package/source/union-to-intersection.d.ts +1 -1
- package/source/union-to-tuple.d.ts +8 -4
- package/source/unwrap-required.d.ts +37 -0
- package/source/words.d.ts +30 -4
- package/source/writable.d.ts +14 -14
- package/source/xor.d.ts +1 -1
|
@@ -5,7 +5,7 @@ import type {IsAny} from './is-any.d.ts';
|
|
|
5
5
|
import type {IsNever} from './is-never.d.ts';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
Create a type that requires exactly one of the given keys
|
|
8
|
+
Create a type that requires exactly one of the given keys or none of the given keys, while keeping the remaining keys as is.
|
|
9
9
|
|
|
10
10
|
@example
|
|
11
11
|
```
|
|
@@ -35,11 +35,11 @@ const responder3: Responder = {
|
|
|
35
35
|
@category Object
|
|
36
36
|
*/
|
|
37
37
|
export type RequireOneOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
38
|
-
IfNotAnyOrNever<ObjectType,
|
|
39
|
-
If<IsNever<KeysType>,
|
|
38
|
+
IfNotAnyOrNever<ObjectType, {
|
|
39
|
+
ifNot: If<IsNever<KeysType>,
|
|
40
40
|
ObjectType,
|
|
41
|
-
_RequireOneOrNone<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType
|
|
42
|
-
|
|
41
|
+
_RequireOneOrNone<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType>>>;
|
|
42
|
+
}>;
|
|
43
43
|
|
|
44
44
|
type _RequireOneOrNone<ObjectType, KeysType extends keyof ObjectType> = (
|
|
45
45
|
| RequireExactlyOne<ObjectType, KeysType>
|
|
@@ -3,12 +3,14 @@ import type {IsNever} from './is-never.d.ts';
|
|
|
3
3
|
import type {Simplify} from './simplify.d.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
Create a
|
|
6
|
+
Create a deeply required version of another type.
|
|
7
7
|
|
|
8
8
|
Use-cases:
|
|
9
9
|
- Creating optional configuration interfaces where the underlying implementation still requires all options to be fully specified.
|
|
10
10
|
- Modeling the resulting type after a deep merge with a set of defaults.
|
|
11
11
|
|
|
12
|
+
Use [`Required<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype) if you only need one level deep.
|
|
13
|
+
|
|
12
14
|
@example
|
|
13
15
|
```
|
|
14
16
|
import type {RequiredDeep} from 'type-fest';
|
package/source/schema.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {ApplyDefaultOptions} from './internal/object.d.ts';
|
|
2
2
|
import type {IfNotAnyOrNever, NonRecursiveType} from './internal/type.d.ts';
|
|
3
|
+
import type {IsAny} from './is-any.d.ts';
|
|
4
|
+
import type {IsUnknown} from './is-unknown.d.ts';
|
|
3
5
|
import type {OptionalKeysOf} from './optional-keys-of.d.ts';
|
|
4
6
|
import type {Simplify} from './simplify.d.ts';
|
|
5
7
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
@@ -91,18 +93,24 @@ const userMaskSettings: UserMask = {
|
|
|
91
93
|
@category Object
|
|
92
94
|
*/
|
|
93
95
|
export type Schema<Type, Value, Options extends SchemaOptions = {}> =
|
|
94
|
-
IfNotAnyOrNever<Type,
|
|
95
|
-
_Schema<Type, Value, ApplyDefaultOptions<SchemaOptions, DefaultSchemaOptions, Options
|
|
96
|
-
|
|
96
|
+
IfNotAnyOrNever<Type, {
|
|
97
|
+
ifNot: _Schema<Type, Value, ApplyDefaultOptions<SchemaOptions, DefaultSchemaOptions, Options>>;
|
|
98
|
+
ifAny: Value;
|
|
99
|
+
ifNever: Value;
|
|
100
|
+
}>;
|
|
97
101
|
|
|
98
102
|
type _Schema<Type, Value, Options extends Required<SchemaOptions>> =
|
|
99
|
-
Type extends
|
|
103
|
+
IsAny<Type> extends true
|
|
100
104
|
? Value
|
|
101
|
-
: Type extends
|
|
102
|
-
?
|
|
105
|
+
: IsUnknown<Type> extends true
|
|
106
|
+
? Value
|
|
107
|
+
: Type extends NonRecursiveType | Map<unknown, unknown> | Set<unknown> | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
|
|
103
108
|
? Value
|
|
104
|
-
:
|
|
105
|
-
|
|
109
|
+
: Type extends UnknownArray
|
|
110
|
+
? Options['recurseIntoArrays'] extends false
|
|
111
|
+
? Value
|
|
112
|
+
: SchemaHelper<Type, Value, Options>
|
|
113
|
+
: SchemaHelper<Type, Value, Options>;
|
|
106
114
|
|
|
107
115
|
/**
|
|
108
116
|
Internal helper for {@link _Schema}.
|
|
@@ -14,6 +14,7 @@ import type {ScreamingSnakeCase} from 'type-fest';
|
|
|
14
14
|
|
|
15
15
|
const someVariable: ScreamingSnakeCase<'fooBar'> = 'FOO_BAR';
|
|
16
16
|
const someVariableNoSplitOnNumbers: ScreamingSnakeCase<'p2pNetwork', {splitOnNumbers: false}> = 'P2P_NETWORK';
|
|
17
|
+
const someVariableWithPunctuation: ScreamingSnakeCase<'div.card::after', {splitOnPunctuation: true}> = 'DIV_CARD_AFTER';
|
|
17
18
|
|
|
18
19
|
```
|
|
19
20
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import type {NonRecursiveType
|
|
1
|
+
import type {NonRecursiveType} from './internal/index.d.ts';
|
|
2
|
+
import type {IsAny} from './is-any.d.ts';
|
|
3
|
+
import type {NonNullableDeep} from './non-nullable-deep.d.ts';
|
|
2
4
|
import type {Paths} from './paths.d.ts';
|
|
3
5
|
import type {SetNonNullable} from './set-non-nullable.d.ts';
|
|
4
6
|
import type {Simplify} from './simplify.d.ts';
|
|
7
|
+
import type {StringToNumber} from './string-to-number.d.ts';
|
|
5
8
|
import type {UnionToTuple} from './union-to-tuple.d.ts';
|
|
6
9
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
Create a type that makes the specified keys non-nullable (removes `null` and `undefined`), supports deeply nested key paths, and leaves all other keys unchanged.
|
|
10
13
|
|
|
11
|
-
NOTE: Optional modifiers (`?`) are not removed from properties. For example, `SetNonNullableDeep<{foo?: string | null | undefined}, 'foo'>` will result in `{foo?: string}`.
|
|
14
|
+
NOTE: Optional modifiers (`?`) are not removed from properties. For example, `SetNonNullableDeep<{foo?: string | null | undefined}, 'foo'>` will result in `{foo?: string}`. To remove both optional modifiers and nullables, use {@link SetRequiredDeep} in conjunction with this type.
|
|
12
15
|
|
|
13
16
|
@example
|
|
14
17
|
```
|
|
@@ -55,8 +58,9 @@ type ArrayExample2 = SetNonNullableDeep<{a: [(number | null)?, (number | null)?]
|
|
|
55
58
|
|
|
56
59
|
@category Object
|
|
57
60
|
*/
|
|
58
|
-
export type SetNonNullableDeep<BaseType, KeyPaths extends Paths<BaseType>> =
|
|
59
|
-
|
|
61
|
+
export type SetNonNullableDeep<BaseType, KeyPaths extends Paths<BaseType>> = IsAny<KeyPaths> extends true
|
|
62
|
+
? NonNullableDeep<BaseType>
|
|
63
|
+
: SetNonNullableDeepHelper<BaseType, UnionToTuple<KeyPaths>>;
|
|
60
64
|
|
|
61
65
|
/**
|
|
62
66
|
Internal helper for {@link SetNonNullableDeep}.
|
package/source/set-optional.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type {HomomorphicPick} from './internal/index.d.ts';
|
|
|
3
3
|
import type {Simplify} from './simplify.d.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
Create a type that makes the given keys optional
|
|
6
|
+
Create a type that makes the given keys optional, while keeping the remaining keys as is.
|
|
7
7
|
|
|
8
8
|
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional.
|
|
9
9
|
|
|
@@ -32,10 +32,10 @@ export type SetOptional<BaseType, Keys extends keyof BaseType> =
|
|
|
32
32
|
type _SetOptional<BaseType, Keys extends keyof BaseType> =
|
|
33
33
|
BaseType extends unknown // To distribute `BaseType` when it's a union type.
|
|
34
34
|
? Simplify<
|
|
35
|
-
|
|
36
|
-
Except<BaseType, Keys>
|
|
37
|
-
|
|
38
|
-
Partial<HomomorphicPick<BaseType, Keys>>
|
|
35
|
+
// Pick just the keys that are readonly from the base type.
|
|
36
|
+
Except<BaseType, Keys>
|
|
37
|
+
// Pick the keys that should be mutable from the base type and make them mutable.
|
|
38
|
+
& Partial<HomomorphicPick<BaseType, Keys>>
|
|
39
39
|
>
|
|
40
40
|
: never;
|
|
41
41
|
|
package/source/set-readonly.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type {HomomorphicPick} from './internal/index.d.ts';
|
|
|
3
3
|
import type {Simplify} from './simplify.d.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
Create a type that makes the given keys readonly
|
|
6
|
+
Create a type that makes the given keys readonly, while keeping the remaining keys as is.
|
|
7
7
|
|
|
8
8
|
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are readonly.
|
|
9
9
|
|
|
@@ -32,8 +32,8 @@ export type SetReadonly<BaseType, Keys extends keyof BaseType> =
|
|
|
32
32
|
export type _SetReadonly<BaseType, Keys extends keyof BaseType> =
|
|
33
33
|
BaseType extends unknown // To distribute `BaseType` when it's a union type.
|
|
34
34
|
? Simplify<
|
|
35
|
-
Except<BaseType, Keys>
|
|
36
|
-
Readonly<HomomorphicPick<BaseType, Keys>>
|
|
35
|
+
Except<BaseType, Keys>
|
|
36
|
+
& Readonly<HomomorphicPick<BaseType, Keys>>
|
|
37
37
|
>
|
|
38
38
|
: never;
|
|
39
39
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type {IsAny} from './is-any.d.ts';
|
|
2
|
-
import type {NonRecursiveType
|
|
2
|
+
import type {NonRecursiveType} from './internal/index.d.ts';
|
|
3
3
|
import type {Paths} from './paths.d.ts';
|
|
4
4
|
import type {SetRequired} from './set-required.d.ts';
|
|
5
5
|
import type {SimplifyDeep} from './simplify-deep.d.ts';
|
|
6
6
|
import type {UnionToTuple} from './union-to-tuple.d.ts';
|
|
7
7
|
import type {RequiredDeep} from './required-deep.d.ts';
|
|
8
8
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
9
|
+
import type {StringToNumber} from './string-to-number.d.ts';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
Create a type that makes the given keys required
|
|
12
|
+
Create a type that makes the given keys required, with support for deeply nested key paths, while keeping the remaining keys as is.
|
|
12
13
|
|
|
13
14
|
Use-case: Selectively make nested properties required in complex types like models.
|
|
14
15
|
|
package/source/set-required.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type {Except} from './except.d.ts';
|
|
2
2
|
import type {If} from './if.d.ts';
|
|
3
3
|
import type {HomomorphicPick, IsArrayReadonly} from './internal/index.d.ts';
|
|
4
|
-
import type {OptionalKeysOf} from './optional-keys-of.d.ts';
|
|
5
4
|
import type {Simplify} from './simplify.d.ts';
|
|
6
5
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
Create a type that makes the given keys required
|
|
8
|
+
Create a type that makes the given keys required, while keeping the remaining keys as is.
|
|
10
9
|
|
|
11
10
|
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
|
|
12
11
|
|
|
@@ -43,9 +42,9 @@ type _SetRequired<BaseType, Keys extends keyof BaseType> =
|
|
|
43
42
|
: never
|
|
44
43
|
: Simplify<
|
|
45
44
|
// Pick just the keys that are optional from the base type.
|
|
46
|
-
Except<BaseType, Keys>
|
|
45
|
+
Except<BaseType, Keys>
|
|
47
46
|
// Pick the keys that should be required from the base type and make them required.
|
|
48
|
-
Required<HomomorphicPick<BaseType, Keys>>
|
|
47
|
+
& Required<HomomorphicPick<BaseType, Keys>>
|
|
49
48
|
>;
|
|
50
49
|
|
|
51
50
|
/**
|
|
@@ -57,19 +56,21 @@ type SetArrayRequired<
|
|
|
57
56
|
Counter extends any[] = [],
|
|
58
57
|
Accumulator extends UnknownArray = [],
|
|
59
58
|
> = TArray extends unknown // For distributing `TArray` when it's a union
|
|
60
|
-
? keyof TArray
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
? '0' extends keyof TArray
|
|
60
|
+
? TArray extends readonly [(infer First)?, ...infer Rest]
|
|
61
|
+
// A tuple allows fewer than one element only when its first element is optional. Written in exactly this shape because equivalent ones, such as `[] extends TArray`, are several times slower.
|
|
62
|
+
// Unlike the other array loops, this one has no `any` guard above it, so the check is wrapped in tuples to stop `any` from matching both branches.
|
|
63
|
+
? [TArray] extends [readonly [unknown, ...unknown[]]]
|
|
64
|
+
? SetArrayRequired<Rest, Keys, [...Counter, any], [...Accumulator, First]>
|
|
65
|
+
: `${Counter['length']}` extends `${Keys & (string | number)}` // If the current index needs to be required
|
|
67
66
|
? SetArrayRequired<Rest, Keys, [...Counter, any], [...Accumulator, First]>
|
|
68
67
|
// If the current element is optional, but it doesn't need to be required,
|
|
69
68
|
// then we can exit early, since no further elements can now be made required.
|
|
70
69
|
: [...Accumulator, ...TArray]
|
|
71
|
-
: SetArrayRequired<Rest, Keys, [...Counter, any], [...Accumulator, TArray[0]]>
|
|
72
70
|
: never // Should never happen, since `[(infer F)?, ...infer R]` is a top-type for arrays.
|
|
71
|
+
// Exit if `TArray` is empty (e.g., []), or
|
|
72
|
+
// `TArray` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`).
|
|
73
|
+
: [...Accumulator, ...TArray]
|
|
73
74
|
: never; // Should never happen
|
|
74
75
|
|
|
75
76
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {NonRecursiveType, UnionMin,
|
|
1
|
+
import type {NonRecursiveType, UnionMin, TupleLength, StaticPartOfArray, VariablePartOfArray, IsArrayReadonly, SetArrayAccess, ApplyDefaultOptions} from './internal/index.d.ts';
|
|
2
|
+
import type {UnionMax} from './union-max.d.ts';
|
|
2
3
|
import type {IsNever} from './is-never.d.ts';
|
|
3
4
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
4
5
|
|
|
@@ -106,11 +107,12 @@ export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOp
|
|
|
106
107
|
Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
|
|
107
108
|
*/
|
|
108
109
|
type SharedObjectUnionFieldsDeep<Union, Options extends Required<SharedUnionFieldsDeepOptions>> =
|
|
109
|
-
//
|
|
110
|
-
|
|
110
|
+
// Extract the shared keys from the union. Throughout this type, use `Keys` instead of `keyof Union`
|
|
111
|
+
// to prevent the mapped type from distributing over the union.
|
|
112
|
+
keyof Union extends infer Keys extends keyof Union
|
|
111
113
|
? IsNever<Keys> extends false
|
|
112
114
|
? {
|
|
113
|
-
[Key in
|
|
115
|
+
[Key in Keys]:
|
|
114
116
|
Union[Key] extends NonRecursiveType
|
|
115
117
|
? Union[Key]
|
|
116
118
|
// Remove `undefined` from the union to support optional
|
|
@@ -66,14 +66,14 @@ function displayPetInfoWithSharedUnionFields(petInfo: SharedUnionFields<Cat | Do
|
|
|
66
66
|
@category Union
|
|
67
67
|
*/
|
|
68
68
|
export type SharedUnionFields<Union> =
|
|
69
|
-
Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
Extract<Union, NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown> | UnknownArray> extends infer SkippedMembers
|
|
70
|
+
? Exclude<Union, SkippedMembers> extends infer RelevantMembers
|
|
71
|
+
? // eslint-disable-line @stylistic/operator-linebreak
|
|
72
|
+
| SkippedMembers
|
|
73
|
+
| (IsNever<RelevantMembers> extends true
|
|
74
|
+
? never
|
|
75
|
+
: Simplify<Pick<RelevantMembers, keyof RelevantMembers>>)
|
|
76
|
+
: never
|
|
77
|
+
: never;
|
|
78
78
|
|
|
79
79
|
export {};
|
package/source/snake-case.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {SnakeCase} from 'type-fest';
|
|
|
16
16
|
const someVariable: SnakeCase<'fooBar'> = 'foo_bar';
|
|
17
17
|
const noSplitOnNumbers: SnakeCase<'p2pNetwork'> = 'p2p_network';
|
|
18
18
|
const splitOnNumbers: SnakeCase<'p2pNetwork', {splitOnNumbers: true}> = 'p_2_p_network';
|
|
19
|
+
const splitOnPunctuation: SnakeCase<'div.card::after', {splitOnPunctuation: true}> = 'div_card_after';
|
|
19
20
|
|
|
20
21
|
// Advanced
|
|
21
22
|
|
|
@@ -51,6 +51,13 @@ const splitOnNumbers: SnakeCasedPropertiesDeep<{line1: {line2: [{line3: string}]
|
|
|
51
51
|
],
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
|
+
|
|
55
|
+
const splitOnPunctuation: SnakeCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
|
|
56
|
+
'user_info': {
|
|
57
|
+
'user_id': 1,
|
|
58
|
+
'user_name': 'Tom',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
54
61
|
```
|
|
55
62
|
|
|
56
63
|
@category Change case
|
|
@@ -4,7 +4,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
|
4
4
|
import type {WordsOptions} from './words.d.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
Convert object properties to snake case
|
|
7
|
+
Convert top-level object properties to snake case.
|
|
8
8
|
|
|
9
9
|
This can be useful when, for example, converting some API types from a different style.
|
|
10
10
|
|
|
@@ -28,6 +28,10 @@ const result: SnakeCasedProperties<User> = {
|
|
|
28
28
|
const splitOnNumbers: SnakeCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
|
|
29
29
|
'line_1': 'string',
|
|
30
30
|
};
|
|
31
|
+
|
|
32
|
+
const splitOnPunctuation: SnakeCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
|
|
33
|
+
'foo_bar': 'string',
|
|
34
|
+
};
|
|
31
35
|
```
|
|
32
36
|
|
|
33
37
|
@category Change case
|
package/source/some-extend.d.ts
CHANGED
|
@@ -95,9 +95,14 @@ type B = SomeExtend<[1?, 2?, '3'?], string | undefined>;
|
|
|
95
95
|
@category Array
|
|
96
96
|
*/
|
|
97
97
|
export type SomeExtend<TArray extends UnknownArray, Type, Options extends SomeExtendOptions = {}> =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
IfNotAnyOrNever<CollapseRestElement<TArray>, {
|
|
99
|
+
ifNot: _SomeExtend<CollapseRestElement<TArray>, Type, ApplyDefaultOptions<SomeExtendOptions, DefaultSomeExtendOptions, Options>>;
|
|
100
|
+
ifAny: false;
|
|
101
|
+
ifNever: false;
|
|
102
|
+
}>;
|
|
103
|
+
|
|
104
|
+
// Kept free of `IfNotAnyOrNever` so that it stays tail-recursive, which allows it to handle long arrays.
|
|
105
|
+
type _SomeExtend<TArray extends UnknownArray, Type, Options extends Required<SomeExtendOptions>> =
|
|
101
106
|
TArray extends readonly [infer First, ...infer Rest]
|
|
102
107
|
? IsNever<First> extends true
|
|
103
108
|
? Or<Or<IsNever<Type>, IsAny<Type>>, Not<Options['strictNever']>> extends true
|
|
@@ -107,7 +112,6 @@ type _SomeExtend<TArray extends UnknownArray, Type, Options extends Required<Som
|
|
|
107
112
|
: First extends Type
|
|
108
113
|
? true
|
|
109
114
|
: _SomeExtend<Rest, Type, Options>
|
|
110
|
-
: false
|
|
111
|
-
false, false>;
|
|
115
|
+
: false;
|
|
112
116
|
|
|
113
117
|
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
|
|
2
2
|
import type {ApplyDefaultOptions} from './internal/object.d.ts';
|
|
3
|
-
import type {IsOptionalKeyOf} from './is-optional-key-of.d.ts';
|
|
4
3
|
import type {IsArrayReadonly} from './internal/array.d.ts';
|
|
5
4
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
6
5
|
import type {If} from './if.d.ts';
|
|
@@ -65,10 +64,12 @@ export type SplitOnRestElement<
|
|
|
65
64
|
Options extends SplitOnRestElementOptions = {},
|
|
66
65
|
> =
|
|
67
66
|
Array_ extends unknown // For distributing `Array_`
|
|
68
|
-
? IfNotAnyOrNever<Array_,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
? IfNotAnyOrNever<Array_, {
|
|
68
|
+
ifNot: _SplitOnRestElement<
|
|
69
|
+
Array_,
|
|
70
|
+
ApplyDefaultOptions<SplitOnRestElementOptions, DefaultSplitOnRestElementOptions, Options>
|
|
71
|
+
>;
|
|
72
|
+
}> extends infer Result extends UnknownArray
|
|
72
73
|
? If<IsArrayReadonly<Array_>, Readonly<Result>, Result>
|
|
73
74
|
: never // Should never happen
|
|
74
75
|
: never; // Should never happen
|
|
@@ -82,25 +83,27 @@ export type _SplitOnRestElement<
|
|
|
82
83
|
HeadAcc extends UnknownArray = [],
|
|
83
84
|
TailAcc extends UnknownArray = [],
|
|
84
85
|
> =
|
|
85
|
-
keyof Array_
|
|
86
|
-
// Enters this branch, if `Array_`
|
|
87
|
-
|
|
88
|
-
? Array_ extends readonly [...infer Rest, infer Last]
|
|
89
|
-
? _SplitOnRestElement<Rest, Options, HeadAcc, [Last, ...TailAcc]> // Accumulate elements that are present after the rest element.
|
|
90
|
-
: [HeadAcc, Array_ extends readonly [] ? [] : Array_, TailAcc] // Add the rest element between the accumulated elements.
|
|
91
|
-
: Array_ extends readonly [(infer First)?, ...infer Rest]
|
|
86
|
+
'0' extends keyof Array_
|
|
87
|
+
// Enters this branch, if `Array_` starts with a non-rest element (e.g., `[string, number]` or `[string, ...number[]]`).
|
|
88
|
+
? Array_ extends readonly [(infer First)?, ...infer Rest]
|
|
92
89
|
? _SplitOnRestElement<
|
|
93
90
|
Rest, Options,
|
|
94
91
|
[
|
|
95
92
|
...HeadAcc,
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
// A tuple allows fewer than one element only when its first element is optional. Written in exactly this shape because equivalent ones, such as `[] extends Array_`, are several times slower.
|
|
94
|
+
...Array_ extends readonly [unknown, ...unknown[]]
|
|
95
|
+
? [First]
|
|
96
|
+
: Options['preserveOptionalModifier'] extends false
|
|
98
97
|
? [If<IsExactOptionalPropertyTypesEnabled, First, First | undefined>] // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
|
|
99
|
-
: [First?]
|
|
100
|
-
: [First],
|
|
98
|
+
: [First?],
|
|
101
99
|
],
|
|
102
100
|
TailAcc
|
|
103
101
|
> // Accumulate elements that are present before the rest element.
|
|
104
|
-
: never
|
|
102
|
+
: never // Should never happen, since `[(infer First)?, ...infer Rest]` is a top-type for arrays.
|
|
103
|
+
// Enters this branch, if `Array_` is empty (e.g., []),
|
|
104
|
+
// or `Array_` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`).
|
|
105
|
+
: Array_ extends readonly [...infer Rest, infer Last]
|
|
106
|
+
? _SplitOnRestElement<Rest, Options, HeadAcc, [Last, ...TailAcc]> // Accumulate elements that are present after the rest element.
|
|
107
|
+
: [HeadAcc, Array_ extends readonly [] ? [] : Array_, TailAcc]; // Add the rest element between the accumulated elements.
|
|
105
108
|
|
|
106
109
|
export {};
|
package/source/split.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {And} from './and.d.ts';
|
|
2
2
|
import type {ApplyDefaultOptions, Not} from './internal/index.d.ts';
|
|
3
|
-
import type {IsStringLiteral} from './is-literal.d.ts';
|
|
3
|
+
import type {IsStringLiteral} from './is-string-literal.d.ts';
|
|
4
4
|
import type {Or} from './or.d.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -64,27 +64,38 @@ export type Split<
|
|
|
64
64
|
Delimiter extends string,
|
|
65
65
|
Options extends SplitOptions = {},
|
|
66
66
|
> =
|
|
67
|
-
|
|
67
|
+
_Split<S, Delimiter, ApplyDefaultOptions<SplitOptions, DefaultSplitOptions, Options>>;
|
|
68
68
|
|
|
69
|
-
type
|
|
69
|
+
type _Split<
|
|
70
70
|
S extends string,
|
|
71
71
|
Delimiter extends string,
|
|
72
72
|
Options extends Required<SplitOptions>,
|
|
73
|
-
Accumulator extends string[] = [],
|
|
74
73
|
> = S extends string // For distributing `S`
|
|
75
74
|
? Delimiter extends string // For distributing `Delimiter`
|
|
76
75
|
// If `strictLiteralChecks` is `false` OR `S` and `Delimiter` both are string literals, then perform the split
|
|
77
76
|
? Or<Not<Options['strictLiteralChecks']>, And<IsStringLiteral<S>, IsStringLiteral<Delimiter>>> extends true
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
: Delimiter extends ''
|
|
81
|
-
? S extends ''
|
|
82
|
-
? Accumulator
|
|
83
|
-
: [...Accumulator, S]
|
|
84
|
-
: [...Accumulator, S]
|
|
77
|
+
// The `extends infer` step keeps `SplitOnDelimiter` out of this conditional's tail-recursion chain, so the loop gets the full recursion budget to itself.
|
|
78
|
+
? SplitOnDelimiter<S, Delimiter> extends infer Result ? Result : never
|
|
85
79
|
// Otherwise, return `string[]`
|
|
86
80
|
: string[]
|
|
87
81
|
: never // Should never happen
|
|
88
82
|
: never; // Should never happen
|
|
89
83
|
|
|
84
|
+
/**
|
|
85
|
+
Splits `S` on `Delimiter`.
|
|
86
|
+
|
|
87
|
+
`S` and `Delimiter` must already be distributed, so that the checks performed by `_Split` do not have to be repeated on every recursion step.
|
|
88
|
+
*/
|
|
89
|
+
type SplitOnDelimiter<
|
|
90
|
+
S extends string,
|
|
91
|
+
Delimiter extends string,
|
|
92
|
+
Accumulator extends string[] = [],
|
|
93
|
+
> = S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
94
|
+
? SplitOnDelimiter<Tail, Delimiter, [...Accumulator, Head]>
|
|
95
|
+
: Delimiter extends ''
|
|
96
|
+
? S extends ''
|
|
97
|
+
? Accumulator
|
|
98
|
+
: [...Accumulator, S]
|
|
99
|
+
: [...Accumulator, S];
|
|
100
|
+
|
|
90
101
|
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {StringToArray} from './string-to-array.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Returns the length of the given string.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {StringLength} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type A = StringLength<'abcde'>;
|
|
11
|
+
//=> 5
|
|
12
|
+
|
|
13
|
+
type B = StringLength<'abcde' | 'fgh'>;
|
|
14
|
+
//=> 3 | 5
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
For non-literal strings, the result is `number` because the length of a non-literal string can be any number.
|
|
18
|
+
|
|
19
|
+
@example
|
|
20
|
+
```
|
|
21
|
+
import type {StringLength} from 'type-fest';
|
|
22
|
+
|
|
23
|
+
type A = StringLength<string>;
|
|
24
|
+
//=> number
|
|
25
|
+
|
|
26
|
+
type B = StringLength<Uppercase<string>>;
|
|
27
|
+
//=> number
|
|
28
|
+
|
|
29
|
+
type C = StringLength<`${string}abc`>;
|
|
30
|
+
//=> number
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
@category String
|
|
34
|
+
@category Template literal
|
|
35
|
+
*/
|
|
36
|
+
export type StringLength<S extends string> = StringToArray<S>['length'];
|
|
37
|
+
|
|
38
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {IsNumericLiteral} from './is-literal.d.ts';
|
|
1
|
+
import type {IsNumericLiteral} from './is-numeric-literal.d.ts';
|
|
2
2
|
import type {IsNegative} from './numeric.d.ts';
|
|
3
|
+
import type {DigitCharacter} from './characters.d.ts';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
Returns a new string which contains the specified number of copies of a given string, just like `String#repeat()`.
|
|
@@ -9,9 +10,9 @@ Returns a new string which contains the specified number of copies of a given st
|
|
|
9
10
|
import type {StringRepeat} from 'type-fest';
|
|
10
11
|
|
|
11
12
|
declare function stringRepeat<
|
|
12
|
-
|
|
13
|
+
S extends string,
|
|
13
14
|
Count extends number,
|
|
14
|
-
>(input:
|
|
15
|
+
>(input: S, count: Count): StringRepeat<S, Count>;
|
|
15
16
|
|
|
16
17
|
// The return type is the exact string literal, not just `string`.
|
|
17
18
|
|
|
@@ -22,28 +23,54 @@ stringRepeat('=', 3);
|
|
|
22
23
|
//=> '==='
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
Note: If the specified count has a decimal part, the decimal part will be ignored.
|
|
27
|
+
|
|
28
|
+
@example
|
|
29
|
+
```
|
|
30
|
+
import type {StringRepeat} from 'type-fest';
|
|
31
|
+
|
|
32
|
+
type DecimalCount = StringRepeat<'foo', 2.5>;
|
|
33
|
+
//=> 'foofoo'
|
|
34
|
+
```
|
|
35
|
+
|
|
25
36
|
@category String
|
|
26
37
|
@category Template literal
|
|
27
38
|
*/
|
|
28
|
-
export type StringRepeat<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Input extends string,
|
|
35
|
-
Count extends number,
|
|
36
|
-
Counter extends never[] = [],
|
|
37
|
-
Accumulator extends string = '',
|
|
38
|
-
> =
|
|
39
|
-
IsNegative<Count> extends true
|
|
40
|
-
? never
|
|
41
|
-
: Input extends ''
|
|
42
|
-
? ''
|
|
43
|
-
: Count extends Counter['length']
|
|
44
|
-
? Accumulator
|
|
39
|
+
export type StringRepeat<S extends string, Count extends number> =
|
|
40
|
+
Count extends unknown // To distribute `Count`
|
|
41
|
+
? IsNegative<Count> extends true
|
|
42
|
+
? never
|
|
43
|
+
: S extends ''
|
|
44
|
+
? ''
|
|
45
45
|
: IsNumericLiteral<Count> extends false
|
|
46
46
|
? string
|
|
47
|
-
:
|
|
47
|
+
: `${Count}` extends `${string}e${string}`
|
|
48
|
+
? string
|
|
49
|
+
: BuildStringDigitByDigit<S, `${Count}`>
|
|
50
|
+
: never;
|
|
51
|
+
|
|
52
|
+
type BuildStringDigitByDigit<S extends string, Count extends string, Accumulator extends string = ''> =
|
|
53
|
+
Count extends `${infer First extends DigitCharacter}${infer Rest}`
|
|
54
|
+
? BuildStringDigitByDigit<
|
|
55
|
+
S,
|
|
56
|
+
Rest,
|
|
57
|
+
`${RepeatStringTenTimes<Accumulator>}${DigitStringRepeat<S, First>}`
|
|
58
|
+
>
|
|
59
|
+
: Accumulator;
|
|
60
|
+
|
|
61
|
+
type RepeatStringTenTimes<S extends string> = `${S}${S}${S}${S}${S}${S}${S}${S}${S}${S}`;
|
|
62
|
+
|
|
63
|
+
type DigitStringRepeat<S extends string, Digit extends DigitCharacter> = [
|
|
64
|
+
'',
|
|
65
|
+
`${S}`,
|
|
66
|
+
`${S}${S}`,
|
|
67
|
+
`${S}${S}${S}`,
|
|
68
|
+
`${S}${S}${S}${S}`,
|
|
69
|
+
`${S}${S}${S}${S}${S}`,
|
|
70
|
+
`${S}${S}${S}${S}${S}${S}`,
|
|
71
|
+
`${S}${S}${S}${S}${S}${S}${S}`,
|
|
72
|
+
`${S}${S}${S}${S}${S}${S}${S}${S}`,
|
|
73
|
+
`${S}${S}${S}${S}${S}${S}${S}${S}${S}`,
|
|
74
|
+
][Digit];
|
|
48
75
|
|
|
49
76
|
export {};
|
package/source/string-slice.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {Join} from './join.d.ts';
|
|
2
2
|
import type {ArraySlice} from './array-slice.d.ts';
|
|
3
|
-
import type {StringToArray} from './
|
|
3
|
+
import type {StringToArray} from './string-to-array.d.ts';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
Returns a string slice of a given range, just like `String#slice()`.
|