@depup/type-fest 5.4.4-depup.0 → 5.9.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 +5 -0
- package/index.d.ts +23 -8
- package/package.json +17 -11
- package/readme.md +98 -64
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +8 -7
- package/source/all-union-fields.d.ts +18 -18
- package/source/and-all.d.ts +76 -0
- package/source/and.d.ts +4 -3
- package/source/array-length.d.ts +36 -0
- package/source/array-reverse.d.ts +4 -3
- package/source/array-splice.d.ts +26 -26
- package/source/array-tail.d.ts +4 -4
- 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/conditional-pick-deep.d.ts +5 -3
- package/source/conditional-pick.d.ts +6 -4
- 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 +57 -0
- 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-or-equal.d.ts +34 -1
- package/source/greater-than.d.ts +37 -3
- 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 +1 -3
- package/source/int-range.d.ts +3 -5
- package/source/internal/array.d.ts +8 -15
- package/source/internal/keys.d.ts +9 -9
- package/source/internal/numeric.d.ts +19 -27
- package/source/internal/object.d.ts +44 -6
- package/source/internal/string.d.ts +1 -76
- package/source/internal/tuple.d.ts +3 -3
- package/source/internal/type.d.ts +16 -9
- package/source/is-boolean-literal.d.ts +39 -0
- package/source/is-equal.d.ts +0 -1
- 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-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 +40 -4
- package/source/less-than.d.ts +35 -3
- package/source/literal-to-primitive.d.ts +1 -1
- package/source/literal-union.d.ts +1 -1
- package/source/merge-exclusive.d.ts +3 -3
- package/source/merge.d.ts +25 -0
- 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 -23
- package/source/optional.d.ts +31 -0
- package/source/or-all.d.ts +73 -0
- package/source/or.d.ts +4 -11
- 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 +8 -21
- 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 +4 -11
- package/source/set-optional.d.ts +6 -10
- package/source/set-parameter-type.d.ts +2 -2
- package/source/set-readonly.d.ts +4 -8
- package/source/set-required-deep.d.ts +3 -2
- package/source/set-required.d.ts +4 -8
- package/source/shared-union-fields-deep.d.ts +5 -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 +115 -0
- package/source/split-on-rest-element.d.ts +6 -4
- package/source/split.d.ts +1 -1
- package/source/spread.d.ts +1 -5
- 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 +5 -7
- package/source/tsconfig-json.d.ts +40 -8
- package/source/tuple-of.d.ts +42 -8
- package/source/typed-array.d.ts +1 -0
- package/source/union-length.d.ts +27 -0
- package/source/union-member.d.ts +65 -0
- package/source/union-to-intersection.d.ts +1 -1
- package/source/union-to-tuple.d.ts +10 -19
- package/source/unwrap-required.d.ts +37 -0
- package/source/words.d.ts +30 -4
- package/source/writable.d.ts +15 -19
- package/source/xor.d.ts +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions} from './internal/object.d.ts';
|
|
2
|
+
import type {IfNotAnyOrNever, Not} from './internal/type.d.ts';
|
|
3
|
+
import type {IsStringLiteral} from './is-string-literal.d.ts';
|
|
4
|
+
import type {IsNever} from './is-never.d.ts';
|
|
5
|
+
import type {Or} from './or.d.ts';
|
|
6
|
+
import type {If} from './if.d.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
@see {@link RemoveSuffix}
|
|
10
|
+
*/
|
|
11
|
+
export type RemoveSuffixOptions = {
|
|
12
|
+
/**
|
|
13
|
+
When enabled, instantiations with non-literal suffixes (e.g., `string`, `Uppercase<string>`, `` `.${string}` ``) simply return `string`, since their precise structure cannot be statically determined.
|
|
14
|
+
|
|
15
|
+
Note: Disabling this option can produce misleading results that might not reflect the actual runtime behavior.
|
|
16
|
+
For example, ``RemoveSuffix<'report.pdf', `.${string}`, {strict: false}>`` returns `'report'`, but at runtime, suffix could be `'.txt'` (which satisfies `` `.${string}` ``) and removing `'.txt'` from `'report.pdf'` would not result in `'report'`.
|
|
17
|
+
|
|
18
|
+
So, it is recommended to not disable this option unless you are aware of the implications.
|
|
19
|
+
|
|
20
|
+
@default true
|
|
21
|
+
|
|
22
|
+
@example
|
|
23
|
+
```
|
|
24
|
+
import type {RemoveSuffix} from 'type-fest';
|
|
25
|
+
|
|
26
|
+
type A = RemoveSuffix<'report.pdf', `.${string}`, {strict: true}>;
|
|
27
|
+
//=> string
|
|
28
|
+
|
|
29
|
+
type B = RemoveSuffix<'report.pdf', `.${string}`, {strict: false}>;
|
|
30
|
+
//=> 'report'
|
|
31
|
+
|
|
32
|
+
type C = RemoveSuffix<'on-change', string, {strict: true}>;
|
|
33
|
+
//=> string
|
|
34
|
+
|
|
35
|
+
type D = RemoveSuffix<'on-change', string, {strict: false}>;
|
|
36
|
+
//=> 'o'
|
|
37
|
+
|
|
38
|
+
type E = RemoveSuffix<`${number}/${string}`, `/${string}`, {strict: true}>;
|
|
39
|
+
//=> string
|
|
40
|
+
|
|
41
|
+
type F = RemoveSuffix<`${number}/${string}`, `/${string}`, {strict: false}>;
|
|
42
|
+
//=> `${number}`
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Note: This option has no effect when only the input string type is non-literal. For example, ``RemoveSuffix<`${string}.pdf`, '.pdf'>`` will always return `string`.
|
|
46
|
+
|
|
47
|
+
@example
|
|
48
|
+
```
|
|
49
|
+
import type {RemoveSuffix} from 'type-fest';
|
|
50
|
+
|
|
51
|
+
type A = RemoveSuffix<`${string}.pdf`, '.pdf', {strict: true}>;
|
|
52
|
+
//=> string
|
|
53
|
+
|
|
54
|
+
type B = RemoveSuffix<`${string}.pdf`, '.pdf', {strict: false}>;
|
|
55
|
+
//=> string
|
|
56
|
+
|
|
57
|
+
type C = RemoveSuffix<`${number}px`, 'px', {strict: true}>;
|
|
58
|
+
//=> `${number}`
|
|
59
|
+
|
|
60
|
+
type D = RemoveSuffix<`${number}px`, 'px', {strict: false}>;
|
|
61
|
+
//=> `${number}`
|
|
62
|
+
```
|
|
63
|
+
*/
|
|
64
|
+
strict?: boolean;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
type DefaultRemoveSuffixOptions = {
|
|
68
|
+
strict: true;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
Remove the specified suffix from the end of a string.
|
|
73
|
+
|
|
74
|
+
@example
|
|
75
|
+
```
|
|
76
|
+
import type {RemoveSuffix} from 'type-fest';
|
|
77
|
+
|
|
78
|
+
type A = RemoveSuffix<'report.pdf', '.pdf'>;
|
|
79
|
+
//=> 'report'
|
|
80
|
+
|
|
81
|
+
type B = RemoveSuffix<'bg-blue-500' | 'text-green-500' | 'border-slate-500', '-500'>;
|
|
82
|
+
//=> 'bg-blue' | 'border-slate' | 'text-green'
|
|
83
|
+
|
|
84
|
+
type C = RemoveSuffix<'report.pdf', '.txt'>;
|
|
85
|
+
//=> 'report.pdf'
|
|
86
|
+
|
|
87
|
+
type D = RemoveSuffix<`api/${string}/analytics`, '/analytics'>;
|
|
88
|
+
//=> `api/${string}`
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
@see {@link RemoveSuffixOptions}
|
|
92
|
+
|
|
93
|
+
@category String
|
|
94
|
+
@category Template literal
|
|
95
|
+
*/
|
|
96
|
+
export type RemoveSuffix<S extends string, Suffix extends string, Options extends RemoveSuffixOptions = {}> =
|
|
97
|
+
IfNotAnyOrNever<S, {
|
|
98
|
+
ifNot: If<
|
|
99
|
+
IsNever<Suffix>,
|
|
100
|
+
S,
|
|
101
|
+
_RemoveSuffix<S, Suffix, ApplyDefaultOptions<RemoveSuffixOptions, DefaultRemoveSuffixOptions, Options>>
|
|
102
|
+
>;
|
|
103
|
+
}>;
|
|
104
|
+
|
|
105
|
+
type _RemoveSuffix<S extends string, Suffix extends string, Options extends Required<RemoveSuffixOptions>> =
|
|
106
|
+
Suffix extends string // For distributing `Suffix`
|
|
107
|
+
? Or<IsStringLiteral<Suffix>, Not<Options['strict']>> extends true
|
|
108
|
+
? S extends `${infer Rest}${Suffix}`
|
|
109
|
+
? Rest
|
|
110
|
+
: S // Return back `S` when `Suffix` is not present at the end of `S`
|
|
111
|
+
: string // Fallback to `string` when `Suffix` is non-literal and `strict` is enabled
|
|
112
|
+
: never;
|
|
113
|
+
|
|
114
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type {IsLiteral} from './is-literal.d.ts';
|
|
2
|
+
import type {ReadonlyKeysOf} from './readonly-keys-of.d.ts';
|
|
3
|
+
import type {RequiredKeysOf} from './required-keys-of.d.ts';
|
|
4
|
+
import type {OptionalKeysOf} from './optional-keys-of.d.ts';
|
|
5
|
+
import type {OmitIndexSignature} from './omit-index-signature.d.ts';
|
|
6
|
+
import type {SetRequired} from './set-required.d.ts';
|
|
7
|
+
import type {SetReadonly} from './set-readonly.d.ts';
|
|
8
|
+
import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
Rename keys in an object type according to a map of old-to-new names.
|
|
12
|
+
|
|
13
|
+
@example
|
|
14
|
+
```
|
|
15
|
+
import type {RenameKeys} from 'type-fest';
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
id: string;
|
|
19
|
+
firstName: string;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Renamed = RenameKeys<User, {firstName: 'first_name'; createdAt: 'created_at'}>;
|
|
24
|
+
//=> {id: string; first_name: string; created_at: Date}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
```
|
|
29
|
+
import type {RenameKeys} from 'type-fest';
|
|
30
|
+
|
|
31
|
+
type SearchInput = {
|
|
32
|
+
textQuery: string;
|
|
33
|
+
voiceQuery: Blob;
|
|
34
|
+
imageQuery: File;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type Normalized = RenameKeys<SearchInput, {textQuery: 'query'; voiceQuery: 'query'; imageQuery: 'query'}>;
|
|
38
|
+
//=> {query: string | Blob | File}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Note: When multiple source keys map to the same target, the target's value type is the union of the contributors' value types. The target is optional only when every contributor is optional, and is `readonly` when any contributor is `readonly`. With `exactOptionalPropertyTypes` disabled, the value type of a mixed-optionality merge also includes `undefined`.
|
|
42
|
+
|
|
43
|
+
@example
|
|
44
|
+
```
|
|
45
|
+
import type {RenameKeys} from 'type-fest';
|
|
46
|
+
|
|
47
|
+
// All colliding keys are required, so the target is required.
|
|
48
|
+
type A = RenameKeys<{a: 1; b: 2}, {a: 'x'; b: 'x'}>;
|
|
49
|
+
//=> {x: 1 | 2}
|
|
50
|
+
|
|
51
|
+
// All colliding keys are optional, so the target is optional.
|
|
52
|
+
type B = RenameKeys<{a?: 1; b?: 2}, {a: 'x'; b: 'x'}>;
|
|
53
|
+
//=> {x?: 1 | 2}
|
|
54
|
+
|
|
55
|
+
// One of the colliding keys is required, so the target is required.
|
|
56
|
+
type C = RenameKeys<{a: 1; b?: 2}, {a: 'x'; b: 'x'}>;
|
|
57
|
+
//=> {x: 1 | 2}
|
|
58
|
+
|
|
59
|
+
// One of the colliding keys is `readonly`, so the target is `readonly`.
|
|
60
|
+
type D = RenameKeys<{readonly a: 1; b: 2}, {a: 'x'; b: 'x'}>;
|
|
61
|
+
//=> {readonly x: 1 | 2}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
@example
|
|
65
|
+
```
|
|
66
|
+
// @exactOptionalPropertyTypes: false
|
|
67
|
+
import type {RenameKeys} from 'type-fest';
|
|
68
|
+
|
|
69
|
+
// With `exactOptionalPropertyTypes` disabled, a mixed-optionality merge includes `undefined`.
|
|
70
|
+
type E = RenameKeys<{a?: 1; b: 2}, {a: 'x'; b: 'x'}>;
|
|
71
|
+
//=> {x: 1 | 2 | undefined}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Note: A union target distributes, producing one output key per member.
|
|
75
|
+
|
|
76
|
+
@example
|
|
77
|
+
```
|
|
78
|
+
import type {RenameKeys} from 'type-fest';
|
|
79
|
+
|
|
80
|
+
type A = RenameKeys<{a: string}, {a: 'b' | 'c'}>;
|
|
81
|
+
//=> {b: string; c: string}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Note: An entry whose value is not a literal `PropertyKey` (such as `string`) is also ignored, leaving that key's name unchanged.
|
|
85
|
+
|
|
86
|
+
@example
|
|
87
|
+
```
|
|
88
|
+
import type {RenameKeys} from 'type-fest';
|
|
89
|
+
|
|
90
|
+
type A = RenameKeys<{a: 1}, {a: string}>;
|
|
91
|
+
//=> {a: 1}
|
|
92
|
+
|
|
93
|
+
type B = RenameKeys<{a: 1; b: 2}, {a: 'x'; b: symbol}>;
|
|
94
|
+
//=> {x: 1; b: 2}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Note: A rename map entry whose key is not a property of the source type is ignored.
|
|
98
|
+
|
|
99
|
+
@example
|
|
100
|
+
```
|
|
101
|
+
import type {RenameKeys} from 'type-fest';
|
|
102
|
+
|
|
103
|
+
type A = RenameKeys<{a: 1; b: 2}, {a: 'x'; c: 'y'}>;
|
|
104
|
+
//=> {x: 1; b: 2}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
@category Object
|
|
108
|
+
*/
|
|
109
|
+
export type RenameKeys<
|
|
110
|
+
BaseType extends object,
|
|
111
|
+
RenameMap extends Record<PropertyKey, PropertyKey>,
|
|
112
|
+
> = IfNotAnyOrNever<BaseType, {
|
|
113
|
+
ifNot: BaseType extends unknown // For distributing `BaseType`
|
|
114
|
+
? RenameMap extends unknown // For distributing `RenameMap`
|
|
115
|
+
? RenameOnce<BaseType, NormalizeMap<RenameMap>>
|
|
116
|
+
: never
|
|
117
|
+
: never;
|
|
118
|
+
}>;
|
|
119
|
+
|
|
120
|
+
type RenameOnce<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>> =
|
|
121
|
+
RestoreMergedUndefined<BaseType, RenameMap,
|
|
122
|
+
ApplyReadonly<BaseType, RenameMap,
|
|
123
|
+
ApplyRequired<BaseType, RenameMap,
|
|
124
|
+
RenameNaive<BaseType, RenameMap>>>>;
|
|
125
|
+
|
|
126
|
+
type RenameNaive<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>> = {
|
|
127
|
+
// Two keys mapping to one target produce a union value and keep only the first key's modifiers.
|
|
128
|
+
// Like for example, `{a?: 1; b: 2}` with `{a: 'x'; b: 'x'}` produces `{x?: 1 | 2}`, taking `a`'s optional.
|
|
129
|
+
[Key in keyof BaseType as TargetOf<Key, RenameMap>]: Required<BaseType>[Key];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// A merged target kept only one modifier in `RenameNaive`, so re-force these from every contributor.
|
|
133
|
+
type ApplyRequired<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>, Renamed> =
|
|
134
|
+
SetRequired<Renamed, TargetOf<RequiredKeysOf<OmitIndexSignature<BaseType>>, RenameMap> & keyof Renamed>;
|
|
135
|
+
|
|
136
|
+
type ApplyReadonly<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>, Renamed> =
|
|
137
|
+
SetReadonly<Renamed, TargetOf<ReadonlyKeysOf<OmitIndexSignature<BaseType>>, RenameMap> & keyof Renamed>;
|
|
138
|
+
|
|
139
|
+
// `exactOptionalPropertyTypes` off keeps `undefined` on a target that merged a required and an optional source.
|
|
140
|
+
// Source `{a?: 1; x: 2}` with `{a: 'x'}` gives `{x: 1 | 2 | undefined}`.
|
|
141
|
+
type RestoreMergedUndefined<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>, Result> =
|
|
142
|
+
IsExactOptionalPropertyTypesEnabled extends true
|
|
143
|
+
? Result
|
|
144
|
+
: {
|
|
145
|
+
[Key in keyof Result]: Key extends MergedTargets<BaseType, RenameMap>
|
|
146
|
+
? Result[Key] | undefined
|
|
147
|
+
: Result[Key];
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
type MergedTargets<BaseType extends object, RenameMap extends Record<PropertyKey, PropertyKey>> =
|
|
151
|
+
// Targets renamed from both a required and an optional key prefer the required modifier.
|
|
152
|
+
// Required `b` and optional `a` both rename to `x` in `{a?: 1; b: 2}` with `{a: 'x'; b: 'x'}`.
|
|
153
|
+
TargetOf<RequiredKeysOf<OmitIndexSignature<BaseType>>, RenameMap>
|
|
154
|
+
& TargetOf<OptionalKeysOf<OmitIndexSignature<BaseType>>, RenameMap>;
|
|
155
|
+
|
|
156
|
+
type NormalizeMap<RenameMap extends Record<PropertyKey, PropertyKey>> = {
|
|
157
|
+
-readonly [Key in keyof RenameMap as true extends IsLiteral<RenameMap[Key]> ? Key : never]-?: RenameMap[Key];
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
type TargetOf<SourceKey extends PropertyKey, RenameMap extends Record<PropertyKey, PropertyKey>> =
|
|
161
|
+
SourceKey extends keyof RenameMap ? RenameMap[SourceKey] : SourceKey;
|
|
162
|
+
|
|
163
|
+
export {};
|
package/source/replace.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ declare function replace<
|
|
|
27
27
|
>(
|
|
28
28
|
input: Input,
|
|
29
29
|
search: Search,
|
|
30
|
-
replacement: Replacement
|
|
30
|
+
replacement: Replacement,
|
|
31
31
|
): Replace<Input, Search, Replacement>;
|
|
32
32
|
|
|
33
33
|
declare function replaceAll<
|
|
@@ -37,7 +37,7 @@ declare function replaceAll<
|
|
|
37
37
|
>(
|
|
38
38
|
input: Input,
|
|
39
39
|
search: Search,
|
|
40
|
-
replacement: Replacement
|
|
40
|
+
replacement: Replacement,
|
|
41
41
|
): Replace<Input, Search, Replacement, {all: true}>;
|
|
42
42
|
|
|
43
43
|
// The return type is the exact string literal, not just `string`.
|
|
@@ -9,7 +9,7 @@ Requires all of the keys in the given object.
|
|
|
9
9
|
type RequireAll<ObjectType, KeysType extends keyof ObjectType> = Required<Pick<ObjectType, KeysType>>;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
Create a type that requires all of the given keys or none of the given keys
|
|
12
|
+
Create a type that requires all of the given keys or none of the given keys, while keeping the remaining keys as is.
|
|
13
13
|
|
|
14
14
|
Use-cases:
|
|
15
15
|
- Creating interfaces for components with mutually-inclusive keys.
|
|
@@ -40,11 +40,11 @@ const responder2: RequireAllOrNone<Responder, 'text' | 'json'> = {
|
|
|
40
40
|
@category Object
|
|
41
41
|
*/
|
|
42
42
|
export type RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
43
|
-
IfNotAnyOrNever<ObjectType,
|
|
44
|
-
If<IsNever<KeysType>,
|
|
43
|
+
IfNotAnyOrNever<ObjectType, {
|
|
44
|
+
ifNot: If<IsNever<KeysType>,
|
|
45
45
|
ObjectType,
|
|
46
|
-
_RequireAllOrNone<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType
|
|
47
|
-
|
|
46
|
+
_RequireAllOrNone<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType>>>;
|
|
47
|
+
}>;
|
|
48
48
|
|
|
49
49
|
type _RequireAllOrNone<ObjectType, KeysType extends keyof ObjectType> = (
|
|
50
50
|
| RequireAll<ObjectType, KeysType>
|
|
@@ -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 at least one of the given keys
|
|
8
|
+
Create a type that requires at least one of the given keys, while keeping the remaining keys as is.
|
|
9
9
|
|
|
10
10
|
@example
|
|
11
11
|
```
|
|
@@ -29,22 +29,20 @@ export type RequireAtLeastOne<
|
|
|
29
29
|
ObjectType,
|
|
30
30
|
KeysType extends keyof ObjectType = keyof ObjectType,
|
|
31
31
|
> =
|
|
32
|
-
IfNotAnyOrNever<ObjectType,
|
|
33
|
-
If<IsNever<KeysType>,
|
|
32
|
+
IfNotAnyOrNever<ObjectType, {
|
|
33
|
+
ifNot: If<IsNever<KeysType>,
|
|
34
34
|
never,
|
|
35
|
-
_RequireAtLeastOne<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType
|
|
36
|
-
|
|
35
|
+
_RequireAtLeastOne<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType>>>;
|
|
36
|
+
}>;
|
|
37
37
|
|
|
38
38
|
type _RequireAtLeastOne<
|
|
39
39
|
ObjectType,
|
|
40
40
|
KeysType extends keyof ObjectType,
|
|
41
41
|
> = {
|
|
42
42
|
// For each `Key` in `KeysType` make a mapped type:
|
|
43
|
-
[Key in KeysType]-?: Required<Pick<ObjectType, Key>>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// 3. Add the remaining keys not in `KeysType`
|
|
48
|
-
Except<ObjectType, KeysType>;
|
|
43
|
+
[Key in KeysType]-?: Required<Pick<ObjectType, Key>> // 1. Make `Key`'s type required
|
|
44
|
+
& Partial<Pick<ObjectType, Exclude<KeysType, Key>>>; // 2. Make all other keys in `KeysType` optional
|
|
45
|
+
}[KeysType]
|
|
46
|
+
& Except<ObjectType, KeysType>; // 3. Add the remaining keys not in `KeysType`
|
|
49
47
|
|
|
50
48
|
export {};
|
|
@@ -4,7 +4,7 @@ import type {IsAny} from './is-any.d.ts';
|
|
|
4
4
|
import type {IsNever} from './is-never.d.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
Create a type that requires exactly one of the given keys and disallows more
|
|
7
|
+
Create a type that requires exactly one of the given keys and disallows more, while keeping the remaining keys as is.
|
|
8
8
|
|
|
9
9
|
Use-cases:
|
|
10
10
|
- Creating interfaces for components that only need one of the keys to display properly.
|
|
@@ -33,16 +33,16 @@ const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {
|
|
|
33
33
|
@category Object
|
|
34
34
|
*/
|
|
35
35
|
export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
|
|
36
|
-
IfNotAnyOrNever<ObjectType,
|
|
37
|
-
If<IsNever<KeysType>,
|
|
36
|
+
IfNotAnyOrNever<ObjectType, {
|
|
37
|
+
ifNot: If<IsNever<KeysType>,
|
|
38
38
|
never,
|
|
39
|
-
_RequireExactlyOne<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType
|
|
40
|
-
|
|
39
|
+
_RequireExactlyOne<ObjectType, If<IsAny<KeysType>, keyof ObjectType, KeysType>>>;
|
|
40
|
+
}>;
|
|
41
41
|
|
|
42
42
|
type _RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType> =
|
|
43
43
|
{[Key in KeysType]: (
|
|
44
|
-
Required<Pick<ObjectType, Key>>
|
|
45
|
-
Partial<Record<Exclude<KeysType, Key>, never>>
|
|
44
|
+
Required<Pick<ObjectType, Key>>
|
|
45
|
+
& Partial<Record<Exclude<KeysType, Key>, never>>
|
|
46
46
|
)}[KeysType] & Omit<ObjectType, KeysType>;
|
|
47
47
|
|
|
48
48
|
export {};
|
|
@@ -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}.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
Create a type that makes the given keys non-nullable,
|
|
2
|
+
Create a type that makes the given keys non-nullable, while keeping the remaining keys as is.
|
|
3
3
|
|
|
4
4
|
If no keys are given, all keys will be made non-nullable.
|
|
5
5
|
|
|
@@ -15,19 +15,12 @@ type Foo = {
|
|
|
15
15
|
c?: boolean | null;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
// Note: In the following example, `c` can no longer be `null`, but it's still optional.
|
|
18
19
|
type SomeNonNullable = SetNonNullable<Foo, 'b' | 'c'>;
|
|
19
|
-
|
|
20
|
-
// a: number | null;
|
|
21
|
-
// b: string; // Can no longer be undefined.
|
|
22
|
-
// c?: boolean; // Can no longer be null, but is still optional.
|
|
23
|
-
// }
|
|
20
|
+
//=> {a: null | number; b: string; c?: boolean}
|
|
24
21
|
|
|
25
22
|
type AllNonNullable = SetNonNullable<Foo>;
|
|
26
|
-
|
|
27
|
-
// a: number; // Can no longer be null.
|
|
28
|
-
// b: string; // Can no longer be undefined.
|
|
29
|
-
// c?: boolean; // Can no longer be null, but is still optional.
|
|
30
|
-
// }
|
|
23
|
+
//=> {a: number; b: string; c?: boolean}
|
|
31
24
|
```
|
|
32
25
|
|
|
33
26
|
@category Object
|
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
|
|
|
@@ -18,11 +18,7 @@ type Foo = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
|
|
21
|
-
|
|
22
|
-
// a: number;
|
|
23
|
-
// b?: string; // Was already optional and still is.
|
|
24
|
-
// c?: boolean; // Is now optional.
|
|
25
|
-
// }
|
|
21
|
+
//=> {a: number; b?: string; c?: boolean}
|
|
26
22
|
```
|
|
27
23
|
|
|
28
24
|
@category Object
|
|
@@ -36,10 +32,10 @@ export type SetOptional<BaseType, Keys extends keyof BaseType> =
|
|
|
36
32
|
type _SetOptional<BaseType, Keys extends keyof BaseType> =
|
|
37
33
|
BaseType extends unknown // To distribute `BaseType` when it's a union type.
|
|
38
34
|
? Simplify<
|
|
39
|
-
|
|
40
|
-
Except<BaseType, Keys>
|
|
41
|
-
|
|
42
|
-
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>>
|
|
43
39
|
>
|
|
44
40
|
: never;
|
|
45
41
|
|
|
@@ -38,14 +38,14 @@ type MergeObjectToArray<TArray extends UnknownArray, TObject, TArrayCopy extends
|
|
|
38
38
|
: K extends keyof TObject ? TObject[K] : TArray[K]
|
|
39
39
|
}
|
|
40
40
|
: TObject extends object
|
|
41
|
-
// If `TObject` is
|
|
41
|
+
// If `TObject` is an object with number keys like `{0: string, 1: number}`
|
|
42
42
|
? {
|
|
43
43
|
[K in keyof TArray]:
|
|
44
44
|
K extends `${infer NumberK extends number}`
|
|
45
45
|
? NumberK extends keyof TObject ? TObject[NumberK] : TArray[K]
|
|
46
46
|
: number extends K
|
|
47
47
|
// If array key `K` is `number`, means it's a rest parameter, we should set the rest parameter type to corresponding type in `TObject`.
|
|
48
|
-
// example: `
|
|
48
|
+
// example: `MergeObjectToArray<[string, ...boolean[]], {1: number}>` => `[string, ...number[]]`
|
|
49
49
|
? StaticPartOfArray<TArrayCopy>['length'] extends keyof TObject
|
|
50
50
|
? TObject[StaticPartOfArray<TArrayCopy>['length']]
|
|
51
51
|
: TArray[K]
|
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
|
|
|
@@ -18,11 +18,7 @@ type Foo = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
type SomeReadonly = SetReadonly<Foo, 'b' | 'c'>;
|
|
21
|
-
|
|
22
|
-
// a: number;
|
|
23
|
-
// readonly b: string; // Was already readonly and still is.
|
|
24
|
-
// readonly c: boolean; // Is now readonly.
|
|
25
|
-
// }
|
|
21
|
+
//=> {a: number; readonly b: string; readonly c: boolean}
|
|
26
22
|
```
|
|
27
23
|
|
|
28
24
|
@category Object
|
|
@@ -36,8 +32,8 @@ export type SetReadonly<BaseType, Keys extends keyof BaseType> =
|
|
|
36
32
|
export type _SetReadonly<BaseType, Keys extends keyof BaseType> =
|
|
37
33
|
BaseType extends unknown // To distribute `BaseType` when it's a union type.
|
|
38
34
|
? Simplify<
|
|
39
|
-
Except<BaseType, Keys>
|
|
40
|
-
Readonly<HomomorphicPick<BaseType, Keys>>
|
|
35
|
+
Except<BaseType, Keys>
|
|
36
|
+
& Readonly<HomomorphicPick<BaseType, Keys>>
|
|
41
37
|
>
|
|
42
38
|
: never;
|
|
43
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
|
|