@depup/type-fest 5.5.0-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 +1 -1
- package/index.d.ts +16 -8
- package/package.json +8 -6
- package/readme.md +85 -61
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +6 -4
- package/source/all-union-fields.d.ts +18 -18
- package/source/and.d.ts +1 -1
- package/source/array-reverse.d.ts +4 -3
- package/source/array-splice.d.ts +24 -24
- 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/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 +1 -3
- package/source/int-range.d.ts +3 -5
- package/source/internal/array.d.ts +8 -8
- 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 +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-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-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 +3 -3
- package/source/shared-union-fields-deep.d.ts +4 -3
- 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 +6 -4
- package/source/split-on-rest-element.d.ts +6 -4
- package/source/split.d.ts +1 -1
- 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 +1 -0
- package/source/union-length.d.ts +27 -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
|
@@ -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}.
|
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
|
@@ -6,7 +6,7 @@ import type {Simplify} from './simplify.d.ts';
|
|
|
6
6
|
import type {UnknownArray} from './unknown-array.d.ts';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
Create a type that makes the given keys required
|
|
9
|
+
Create a type that makes the given keys required, while keeping the remaining keys as is.
|
|
10
10
|
|
|
11
11
|
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
12
|
|
|
@@ -43,9 +43,9 @@ type _SetRequired<BaseType, Keys extends keyof BaseType> =
|
|
|
43
43
|
: never
|
|
44
44
|
: Simplify<
|
|
45
45
|
// Pick just the keys that are optional from the base type.
|
|
46
|
-
Except<BaseType, Keys>
|
|
46
|
+
Except<BaseType, Keys>
|
|
47
47
|
// Pick the keys that should be required from the base type and make them required.
|
|
48
|
-
Required<HomomorphicPick<BaseType, Keys>>
|
|
48
|
+
& Required<HomomorphicPick<BaseType, Keys>>
|
|
49
49
|
>;
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -106,11 +106,12 @@ export type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOp
|
|
|
106
106
|
Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
|
|
107
107
|
*/
|
|
108
108
|
type SharedObjectUnionFieldsDeep<Union, Options extends Required<SharedUnionFieldsDeepOptions>> =
|
|
109
|
-
//
|
|
110
|
-
|
|
109
|
+
// Extract the shared keys from the union. Throughout this type, use `Keys` instead of `keyof Union`
|
|
110
|
+
// to prevent the mapped type from distributing over the union.
|
|
111
|
+
keyof Union extends infer Keys extends keyof Union
|
|
111
112
|
? IsNever<Keys> extends false
|
|
112
113
|
? {
|
|
113
|
-
[Key in
|
|
114
|
+
[Key in Keys]:
|
|
114
115
|
Union[Key] extends NonRecursiveType
|
|
115
116
|
? Union[Key]
|
|
116
117
|
// 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 {};
|