@depup/type-fest 5.4.4-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 +25 -0
- package/index.d.ts +211 -0
- package/license-cc0 +121 -0
- package/license-mit +9 -0
- package/package.json +85 -0
- package/readme.md +1052 -0
- package/source/all-extend.d.ts +120 -0
- package/source/all-union-fields.d.ts +91 -0
- package/source/and.d.ts +81 -0
- package/source/array-element.d.ts +46 -0
- package/source/array-indices.d.ts +25 -0
- package/source/array-reverse.d.ts +84 -0
- package/source/array-slice.d.ts +132 -0
- package/source/array-splice.d.ts +104 -0
- package/source/array-tail.d.ts +70 -0
- package/source/array-values.d.ts +24 -0
- package/source/arrayable.d.ts +31 -0
- package/source/async-return-type.d.ts +28 -0
- package/source/asyncify.d.ts +25 -0
- package/source/basic.d.ts +38 -0
- package/source/camel-case.d.ts +92 -0
- package/source/camel-cased-properties-deep.d.ts +99 -0
- package/source/camel-cased-properties.d.ts +45 -0
- package/source/characters.d.ts +67 -0
- package/source/conditional-except.d.ts +47 -0
- package/source/conditional-keys.d.ts +63 -0
- package/source/conditional-pick-deep.d.ts +120 -0
- package/source/conditional-pick.d.ts +46 -0
- package/source/conditional-simplify-deep.d.ts +73 -0
- package/source/conditional-simplify.d.ts +50 -0
- package/source/delimiter-case.d.ts +77 -0
- package/source/delimiter-cased-properties-deep.d.ts +108 -0
- package/source/delimiter-cased-properties.d.ts +48 -0
- package/source/distributed-omit.d.ts +96 -0
- package/source/distributed-pick.d.ts +92 -0
- package/source/empty-object.d.ts +51 -0
- package/source/entries.d.ts +64 -0
- package/source/entry.d.ts +67 -0
- package/source/exact.d.ts +73 -0
- package/source/except.d.ts +112 -0
- package/source/exclude-rest-element.d.ts +40 -0
- package/source/exclude-strict.d.ts +51 -0
- package/source/exclusify-union.d.ts +147 -0
- package/source/extends-strict.d.ts +44 -0
- package/source/extract-rest-element.d.ts +30 -0
- package/source/extract-strict.d.ts +51 -0
- package/source/find-global-type.d.ts +68 -0
- package/source/fixed-length-array.d.ts +97 -0
- package/source/get.d.ts +227 -0
- package/source/global-this.d.ts +24 -0
- package/source/globals/index.d.ts +3 -0
- package/source/globals/observable-like.d.ts +78 -0
- package/source/greater-than-or-equal.d.ts +30 -0
- package/source/greater-than.d.ts +58 -0
- package/source/has-optional-keys.d.ts +23 -0
- package/source/has-readonly-keys.d.ts +23 -0
- package/source/has-required-keys.d.ts +61 -0
- package/source/has-writable-keys.d.ts +23 -0
- package/source/if-any.d.ts +28 -0
- package/source/if-empty-object.d.ts +30 -0
- package/source/if-never.d.ts +28 -0
- package/source/if-null.d.ts +28 -0
- package/source/if-unknown.d.ts +28 -0
- package/source/if.d.ts +102 -0
- package/source/includes.d.ts +24 -0
- package/source/int-closed-range.d.ts +47 -0
- package/source/int-range.d.ts +69 -0
- package/source/internal/array.d.ts +151 -0
- package/source/internal/characters.d.ts +65 -0
- package/source/internal/enforce-optional.d.ts +49 -0
- package/source/internal/index.d.ts +11 -0
- package/source/internal/keys.d.ts +100 -0
- package/source/internal/numeric.d.ts +151 -0
- package/source/internal/object.d.ts +292 -0
- package/source/internal/string.d.ts +202 -0
- package/source/internal/tuple.d.ts +79 -0
- package/source/internal/type.d.ts +164 -0
- package/source/invariant-of.d.ts +85 -0
- package/source/is-any.d.ts +31 -0
- package/source/is-equal.d.ts +42 -0
- package/source/is-float.d.ts +43 -0
- package/source/is-integer.d.ts +60 -0
- package/source/is-literal.d.ts +315 -0
- package/source/is-lowercase.d.ts +38 -0
- package/source/is-never.d.ts +56 -0
- package/source/is-null.d.ts +22 -0
- package/source/is-nullable.d.ts +30 -0
- package/source/is-optional-key-of.d.ts +51 -0
- package/source/is-optional.d.ts +28 -0
- package/source/is-readonly-key-of.d.ts +55 -0
- package/source/is-required-key-of.d.ts +51 -0
- package/source/is-tuple.d.ts +92 -0
- package/source/is-undefined.d.ts +22 -0
- package/source/is-union.d.ts +40 -0
- package/source/is-unknown.d.ts +43 -0
- package/source/is-uppercase.d.ts +38 -0
- package/source/is-writable-key-of.d.ts +51 -0
- package/source/iterable-element.d.ts +66 -0
- package/source/join.d.ts +79 -0
- package/source/json-value.d.ts +33 -0
- package/source/jsonifiable.d.ts +37 -0
- package/source/jsonify.d.ts +127 -0
- package/source/kebab-case.d.ts +46 -0
- package/source/kebab-cased-properties-deep.d.ts +65 -0
- package/source/kebab-cased-properties.d.ts +42 -0
- package/source/key-as-string.d.ts +27 -0
- package/source/keys-of-union.d.ts +44 -0
- package/source/last-array-element.d.ts +36 -0
- package/source/less-than-or-equal.d.ts +24 -0
- package/source/less-than.d.ts +28 -0
- package/source/literal-to-primitive-deep.d.ts +71 -0
- package/source/literal-to-primitive.d.ts +38 -0
- package/source/literal-union.d.ts +39 -0
- package/source/merge-deep.d.ts +495 -0
- package/source/merge-exclusive.d.ts +45 -0
- package/source/merge.d.ts +62 -0
- package/source/multidimensional-array.d.ts +38 -0
- package/source/multidimensional-readonly-array.d.ts +38 -0
- package/source/non-empty-object.d.ts +38 -0
- package/source/non-empty-string.d.ts +32 -0
- package/source/non-empty-tuple.d.ts +24 -0
- package/source/numeric.d.ts +226 -0
- package/source/object-merge.d.ts +194 -0
- package/source/omit-deep.d.ts +154 -0
- package/source/omit-index-signature.d.ts +98 -0
- package/source/opaque.d.ts +3 -0
- package/source/optional-keys-of.d.ts +46 -0
- package/source/or.d.ts +89 -0
- package/source/override-properties.d.ts +43 -0
- package/source/package-json.d.ts +710 -0
- package/source/partial-deep.d.ts +155 -0
- package/source/partial-on-undefined-deep.d.ts +81 -0
- package/source/pascal-case.d.ts +51 -0
- package/source/pascal-cased-properties-deep.d.ts +72 -0
- package/source/pascal-cased-properties.d.ts +42 -0
- package/source/paths.d.ts +241 -0
- package/source/pick-deep.d.ts +152 -0
- package/source/pick-index-signature.d.ts +52 -0
- package/source/primitive.d.ts +15 -0
- package/source/promisable.d.ts +27 -0
- package/source/readonly-deep.d.ts +116 -0
- package/source/readonly-keys-of.d.ts +38 -0
- package/source/readonly-tuple.d.ts +34 -0
- package/source/remove-prefix.d.ts +132 -0
- package/source/replace.d.ts +87 -0
- package/source/require-all-or-none.d.ts +54 -0
- package/source/require-at-least-one.d.ts +50 -0
- package/source/require-exactly-one.d.ts +48 -0
- package/source/require-one-or-none.d.ts +49 -0
- package/source/required-deep.d.ts +76 -0
- package/source/required-keys-of.d.ts +38 -0
- package/source/schema.d.ts +119 -0
- package/source/screaming-snake-case.d.ts +30 -0
- package/source/set-field-type.d.ts +67 -0
- package/source/set-non-nullable-deep.d.ts +85 -0
- package/source/set-non-nullable.d.ts +41 -0
- package/source/set-optional.d.ts +46 -0
- package/source/set-parameter-type.d.ts +125 -0
- package/source/set-readonly.d.ts +44 -0
- package/source/set-required-deep.d.ts +64 -0
- package/source/set-required.d.ts +79 -0
- package/source/set-return-type.d.ts +31 -0
- package/source/shared-union-fields-deep.d.ts +180 -0
- package/source/shared-union-fields.d.ts +79 -0
- package/source/simplify-deep.d.ts +117 -0
- package/source/simplify.d.ts +61 -0
- package/source/single-key-object.d.ts +28 -0
- package/source/snake-case.d.ts +47 -0
- package/source/snake-cased-properties-deep.d.ts +65 -0
- package/source/snake-cased-properties.d.ts +42 -0
- package/source/split-on-rest-element.d.ts +106 -0
- package/source/split.d.ts +90 -0
- package/source/spread.d.ts +82 -0
- package/source/string-repeat.d.ts +49 -0
- package/source/string-slice.d.ts +39 -0
- package/source/stringified.d.ts +25 -0
- package/source/structured-cloneable.d.ts +89 -0
- package/source/subtract.d.ts +86 -0
- package/source/sum.d.ts +81 -0
- package/source/tagged-union.d.ts +53 -0
- package/source/tagged.d.ts +263 -0
- package/source/trim.d.ts +29 -0
- package/source/tsconfig-json.d.ts +1324 -0
- package/source/tuple-of.d.ts +80 -0
- package/source/tuple-to-object.d.ts +47 -0
- package/source/tuple-to-union.d.ts +54 -0
- package/source/typed-array.d.ts +19 -0
- package/source/undefined-on-partial-deep.d.ts +83 -0
- package/source/union-to-intersection.d.ts +35 -0
- package/source/union-to-tuple.d.ts +58 -0
- package/source/unknown-array.d.ts +27 -0
- package/source/unknown-map.d.ts +26 -0
- package/source/unknown-record.d.ts +33 -0
- package/source/unknown-set.d.ts +26 -0
- package/source/unwrap-partial.d.ts +33 -0
- package/source/value-of.d.ts +24 -0
- package/source/words.d.ts +122 -0
- package/source/writable-deep.d.ts +84 -0
- package/source/writable-keys-of.d.ts +34 -0
- package/source/writable.d.ts +72 -0
- package/source/xor.d.ts +83 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions, BuiltIns, HasMultipleCallSignatures} from './internal/index.d.ts';
|
|
2
|
+
import type {IsNever} from './is-never.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
@see {@link PartialDeep}
|
|
6
|
+
*/
|
|
7
|
+
export type PartialDeepOptions = {
|
|
8
|
+
/**
|
|
9
|
+
Whether to affect the individual elements of arrays and tuples.
|
|
10
|
+
|
|
11
|
+
@default false
|
|
12
|
+
*/
|
|
13
|
+
readonly recurseIntoArrays?: boolean;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Allows `undefined` values in non-tuple arrays.
|
|
17
|
+
|
|
18
|
+
- When set to `true`, elements of non-tuple arrays can be `undefined`.
|
|
19
|
+
- When set to `false`, only explicitly defined elements are allowed in non-tuple arrays, ensuring stricter type checking.
|
|
20
|
+
|
|
21
|
+
@default false
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
You can allow `undefined` values in non-tuple arrays by passing `{recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}` as the second type argument:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
import type {PartialDeep} from 'type-fest';
|
|
28
|
+
|
|
29
|
+
type Settings = {
|
|
30
|
+
languages: string[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
declare const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true; allowUndefinedInNonTupleArrays: true}>;
|
|
34
|
+
|
|
35
|
+
partialSettings.languages = [undefined]; // OK
|
|
36
|
+
```
|
|
37
|
+
*/
|
|
38
|
+
readonly allowUndefinedInNonTupleArrays?: boolean;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type DefaultPartialDeepOptions = {
|
|
42
|
+
recurseIntoArrays: false;
|
|
43
|
+
allowUndefinedInNonTupleArrays: false;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
Create a type from another type with all keys and nested keys set to optional.
|
|
48
|
+
|
|
49
|
+
Use-cases:
|
|
50
|
+
- Merging a default settings/config object with another object, the second object would be a deep partial of the default object.
|
|
51
|
+
- Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
|
|
52
|
+
|
|
53
|
+
@example
|
|
54
|
+
```
|
|
55
|
+
import type {PartialDeep} from 'type-fest';
|
|
56
|
+
|
|
57
|
+
let settings = {
|
|
58
|
+
textEditor: {
|
|
59
|
+
fontSize: 14,
|
|
60
|
+
fontColor: '#000000',
|
|
61
|
+
fontWeight: 400,
|
|
62
|
+
},
|
|
63
|
+
autocomplete: false,
|
|
64
|
+
autosave: true,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const applySavedSettings = (savedSettings: PartialDeep<typeof settings>) => (
|
|
68
|
+
{...settings, ...savedSettings, textEditor: {...settings.textEditor, ...savedSettings.textEditor}}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
By default, this does not affect elements in array and tuple types. You can change this by passing `{recurseIntoArrays: true}` as the second type argument:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
import type {PartialDeep} from 'type-fest';
|
|
78
|
+
|
|
79
|
+
type Shape = {
|
|
80
|
+
dimensions: [number, number];
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const partialShape: PartialDeep<Shape, {recurseIntoArrays: true}> = {
|
|
84
|
+
dimensions: [], // OK
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
partialShape.dimensions = [15]; // OK
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
@see {@link PartialDeepOptions}
|
|
91
|
+
|
|
92
|
+
@category Object
|
|
93
|
+
@category Array
|
|
94
|
+
@category Set
|
|
95
|
+
@category Map
|
|
96
|
+
*/
|
|
97
|
+
export type PartialDeep<T, Options extends PartialDeepOptions = {}> =
|
|
98
|
+
_PartialDeep<T, ApplyDefaultOptions<PartialDeepOptions, DefaultPartialDeepOptions, Options>>;
|
|
99
|
+
|
|
100
|
+
type _PartialDeep<T, Options extends Required<PartialDeepOptions>> = T extends BuiltIns | ((new (...arguments_: any[]) => unknown))
|
|
101
|
+
? T
|
|
102
|
+
: T extends Map<infer KeyType, infer ValueType>
|
|
103
|
+
? PartialMapDeep<KeyType, ValueType, Options>
|
|
104
|
+
: T extends Set<infer ItemType>
|
|
105
|
+
? PartialSetDeep<ItemType, Options>
|
|
106
|
+
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
107
|
+
? PartialReadonlyMapDeep<KeyType, ValueType, Options>
|
|
108
|
+
: T extends ReadonlySet<infer ItemType>
|
|
109
|
+
? PartialReadonlySetDeep<ItemType, Options>
|
|
110
|
+
: T extends (...arguments_: any[]) => unknown
|
|
111
|
+
? IsNever<keyof T> extends true
|
|
112
|
+
? T // For functions with no properties
|
|
113
|
+
: HasMultipleCallSignatures<T> extends true
|
|
114
|
+
? T
|
|
115
|
+
: ((...arguments_: Parameters<T>) => ReturnType<T>) & PartialObjectDeep<T, Options>
|
|
116
|
+
: T extends object
|
|
117
|
+
? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
|
|
118
|
+
? Options['recurseIntoArrays'] extends true
|
|
119
|
+
? ItemType[] extends T // Test for arrays (non-tuples) specifically
|
|
120
|
+
? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
|
|
121
|
+
? ReadonlyArray<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
|
|
122
|
+
: Array<_PartialDeep<Options['allowUndefinedInNonTupleArrays'] extends false ? ItemType : ItemType | undefined, Options>>
|
|
123
|
+
: PartialObjectDeep<T, Options> // Tuples behave properly
|
|
124
|
+
: T // If they don't opt into array testing, just use the original type
|
|
125
|
+
: PartialObjectDeep<T, Options>
|
|
126
|
+
: unknown;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
|
|
130
|
+
*/
|
|
131
|
+
type PartialMapDeep<KeyType, ValueType, Options extends Required<PartialDeepOptions>> = {} & Map<_PartialDeep<KeyType, Options>, _PartialDeep<ValueType, Options>>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`.
|
|
135
|
+
*/
|
|
136
|
+
type PartialSetDeep<T, Options extends Required<PartialDeepOptions>> = {} & Set<_PartialDeep<T, Options>>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`.
|
|
140
|
+
*/
|
|
141
|
+
type PartialReadonlyMapDeep<KeyType, ValueType, Options extends Required<PartialDeepOptions>> = {} & ReadonlyMap<_PartialDeep<KeyType, Options>, _PartialDeep<ValueType, Options>>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`.
|
|
145
|
+
*/
|
|
146
|
+
type PartialReadonlySetDeep<T, Options extends Required<PartialDeepOptions>> = {} & ReadonlySet<_PartialDeep<T, Options>>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
|
|
150
|
+
*/
|
|
151
|
+
type PartialObjectDeep<ObjectType extends object, Options extends Required<PartialDeepOptions>> = {
|
|
152
|
+
[KeyType in keyof ObjectType]?: _PartialDeep<ObjectType[KeyType], Options>
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type {If} from './if.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions, BuiltIns, LiteralKeyOf} from './internal/index.d.ts';
|
|
3
|
+
import type {IsUnknown} from './is-unknown.d.ts';
|
|
4
|
+
import type {Merge} from './merge.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
@see {@link PartialOnUndefinedDeep}
|
|
8
|
+
*/
|
|
9
|
+
export type PartialOnUndefinedDeepOptions = {
|
|
10
|
+
/**
|
|
11
|
+
Whether to affect the individual elements of arrays and tuples.
|
|
12
|
+
|
|
13
|
+
@default false
|
|
14
|
+
*/
|
|
15
|
+
readonly recurseIntoArrays?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type DefaultPartialOnUndefinedDeepOptions = {
|
|
19
|
+
recurseIntoArrays: false;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Create a deep version of another type where all keys accepting `undefined` type are set to optional.
|
|
24
|
+
|
|
25
|
+
This utility type is recursive, transforming at any level deep. By default, it does not affect arrays and tuples items unless you explicitly pass `{recurseIntoArrays: true}` as the second type argument.
|
|
26
|
+
|
|
27
|
+
Use-cases:
|
|
28
|
+
- Make all properties of a type that can be undefined optional to not have to specify keys with undefined value.
|
|
29
|
+
|
|
30
|
+
@example
|
|
31
|
+
```
|
|
32
|
+
import type {PartialOnUndefinedDeep} from 'type-fest';
|
|
33
|
+
|
|
34
|
+
type Settings = {
|
|
35
|
+
optionA: string;
|
|
36
|
+
optionB: number | undefined;
|
|
37
|
+
subOption: {
|
|
38
|
+
subOptionA: boolean;
|
|
39
|
+
subOptionB: boolean | undefined;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const testSettings: PartialOnUndefinedDeep<Settings> = {
|
|
44
|
+
optionA: 'foo',
|
|
45
|
+
// 👉 optionB is now optional and can be omitted
|
|
46
|
+
subOption: {
|
|
47
|
+
subOptionA: true,
|
|
48
|
+
// 👉 subOptionB is now optional as well and can be omitted
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
@category Object
|
|
54
|
+
*/
|
|
55
|
+
export type PartialOnUndefinedDeep<T, Options extends PartialOnUndefinedDeepOptions = {}> =
|
|
56
|
+
_PartialOnUndefinedDeep<T, ApplyDefaultOptions<PartialOnUndefinedDeepOptions, DefaultPartialOnUndefinedDeepOptions, Options>>;
|
|
57
|
+
|
|
58
|
+
type _PartialOnUndefinedDeep<T, Options extends Required<PartialOnUndefinedDeepOptions>> = T extends Record<any, any> | undefined
|
|
59
|
+
? {[KeyType in keyof T as undefined extends T[KeyType] ? If<IsUnknown<T[KeyType]>, never, KeyType> : never]?: PartialOnUndefinedDeepValue<T[KeyType], Options>} extends infer U // Make a partial type with all value types accepting undefined (and set them optional)
|
|
60
|
+
? Merge<{[KeyType in keyof T as KeyType extends LiteralKeyOf<U> ? never : KeyType]: PartialOnUndefinedDeepValue<T[KeyType], Options>}, U> // Join all remaining keys not treated in U
|
|
61
|
+
: never // Should not happen
|
|
62
|
+
: T;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
Utility type to get the value type by key and recursively call `PartialOnUndefinedDeep` to transform sub-objects.
|
|
66
|
+
*/
|
|
67
|
+
type PartialOnUndefinedDeepValue<T, Options extends Required<PartialOnUndefinedDeepOptions>> = T extends BuiltIns | ((...arguments_: any[]) => unknown)
|
|
68
|
+
? T
|
|
69
|
+
: T extends ReadonlyArray<infer U> // Test if type is array or tuple
|
|
70
|
+
? Options['recurseIntoArrays'] extends true // Check if option is activated
|
|
71
|
+
? U[] extends T // Check if array not tuple
|
|
72
|
+
? readonly U[] extends T
|
|
73
|
+
? ReadonlyArray<_PartialOnUndefinedDeep<U, Options>> // Readonly array treatment
|
|
74
|
+
: Array<_PartialOnUndefinedDeep<U, Options>> // Mutable array treatment
|
|
75
|
+
: _PartialOnUndefinedDeep<{[Key in keyof T]: _PartialOnUndefinedDeep<T[Key], Options>}, Options> // Tuple treatment
|
|
76
|
+
: T
|
|
77
|
+
: T extends Record<any, any> | undefined
|
|
78
|
+
? _PartialOnUndefinedDeep<T, Options>
|
|
79
|
+
: unknown;
|
|
80
|
+
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type {CamelCase, CamelCaseOptions, _DefaultCamelCaseOptions} from './camel-case.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Convert a string literal to pascal-case.
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
import type {PascalCase} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
// Simple
|
|
12
|
+
|
|
13
|
+
const someVariable: PascalCase<'foo-bar'> = 'FooBar';
|
|
14
|
+
const preserveConsecutiveUppercase: PascalCase<'foo-BAR-baz', {preserveConsecutiveUppercase: true}> = 'FooBARBaz';
|
|
15
|
+
|
|
16
|
+
// Advanced
|
|
17
|
+
|
|
18
|
+
type PascalCasedProperties<T> = {
|
|
19
|
+
[K in keyof T as PascalCase<K>]: T[K]
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type RawOptions = {
|
|
23
|
+
'dry-run': boolean;
|
|
24
|
+
'full_family_name': string;
|
|
25
|
+
foo: number;
|
|
26
|
+
BAR: string;
|
|
27
|
+
QUZ_QUX: number;
|
|
28
|
+
'OTHER-FIELD': boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const dbResult: PascalCasedProperties<RawOptions> = {
|
|
32
|
+
DryRun: true,
|
|
33
|
+
FullFamilyName: 'bar.js',
|
|
34
|
+
Foo: 123,
|
|
35
|
+
Bar: 'foo',
|
|
36
|
+
QuzQux: 6,
|
|
37
|
+
OtherField: false,
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
@category Change case
|
|
42
|
+
@category Template literal
|
|
43
|
+
*/
|
|
44
|
+
export type PascalCase<Value, Options extends CamelCaseOptions = {}> =
|
|
45
|
+
_PascalCase<Value, ApplyDefaultOptions<CamelCaseOptions, _DefaultCamelCaseOptions, Options>>;
|
|
46
|
+
|
|
47
|
+
type _PascalCase<Value, Options extends Required<CamelCaseOptions>> = CamelCase<Value, Options> extends string
|
|
48
|
+
? Capitalize<CamelCase<Value, Options>>
|
|
49
|
+
: CamelCase<Value, Options>;
|
|
50
|
+
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type {CamelCaseOptions, _DefaultCamelCaseOptions} from './camel-case.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
3
|
+
import type {PascalCase} from './pascal-case.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Convert object properties to pascal case recursively.
|
|
7
|
+
|
|
8
|
+
This can be useful when, for example, converting some API types from a different style.
|
|
9
|
+
|
|
10
|
+
@see {@link PascalCase}
|
|
11
|
+
@see {@link PascalCasedProperties}
|
|
12
|
+
|
|
13
|
+
@example
|
|
14
|
+
```
|
|
15
|
+
import type {PascalCasedPropertiesDeep} from 'type-fest';
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
userId: number;
|
|
19
|
+
userName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type UserWithFriends = {
|
|
23
|
+
userInfo: User;
|
|
24
|
+
userFriends: User[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const result: PascalCasedPropertiesDeep<UserWithFriends> = {
|
|
28
|
+
UserInfo: {
|
|
29
|
+
UserId: 1,
|
|
30
|
+
UserName: 'Tom',
|
|
31
|
+
},
|
|
32
|
+
UserFriends: [
|
|
33
|
+
{
|
|
34
|
+
UserId: 2,
|
|
35
|
+
UserName: 'Jerry',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
UserId: 3,
|
|
39
|
+
UserName: 'Spike',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const preserveConsecutiveUppercase: PascalCasedPropertiesDeep<{fooBAR: {fooBARBiz: [{fooBARBaz: string}]}}, {preserveConsecutiveUppercase: true}> = {
|
|
45
|
+
FooBAR: {
|
|
46
|
+
FooBARBiz: [{
|
|
47
|
+
FooBARBaz: 'string',
|
|
48
|
+
}],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
@category Change case
|
|
54
|
+
@category Template literal
|
|
55
|
+
@category Object
|
|
56
|
+
*/
|
|
57
|
+
export type PascalCasedPropertiesDeep<Value, Options extends CamelCaseOptions = {}> =
|
|
58
|
+
_PascalCasedPropertiesDeep<Value, ApplyDefaultOptions<CamelCaseOptions, _DefaultCamelCaseOptions, Options>>;
|
|
59
|
+
|
|
60
|
+
type _PascalCasedPropertiesDeep<Value, Options extends Required<CamelCaseOptions>> = Value extends Function | Date | RegExp
|
|
61
|
+
? Value
|
|
62
|
+
: Value extends Array<infer U>
|
|
63
|
+
? Array<_PascalCasedPropertiesDeep<U, Options>>
|
|
64
|
+
: Value extends Set<infer U>
|
|
65
|
+
? Set<_PascalCasedPropertiesDeep<U, Options>>
|
|
66
|
+
: Value extends object
|
|
67
|
+
? {
|
|
68
|
+
[K in keyof Value as PascalCase<K, Options>]: _PascalCasedPropertiesDeep<Value[K], Options>;
|
|
69
|
+
}
|
|
70
|
+
: Value;
|
|
71
|
+
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {CamelCaseOptions, _DefaultCamelCaseOptions} from './camel-case.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
3
|
+
import type {PascalCase} from './pascal-case.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Convert object properties to pascal case but not recursively.
|
|
7
|
+
|
|
8
|
+
This can be useful when, for example, converting some API types from a different style.
|
|
9
|
+
|
|
10
|
+
@see {@link PascalCase}
|
|
11
|
+
@see {@link PascalCasedPropertiesDeep}
|
|
12
|
+
|
|
13
|
+
@example
|
|
14
|
+
```
|
|
15
|
+
import type {PascalCasedProperties} from 'type-fest';
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
userId: number;
|
|
19
|
+
userName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const result: PascalCasedProperties<User> = {
|
|
23
|
+
UserId: 1,
|
|
24
|
+
UserName: 'Tom',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const preserveConsecutiveUppercase: PascalCasedProperties<{fooBAR: string}, {preserveConsecutiveUppercase: true}> = {
|
|
28
|
+
FooBAR: 'string',
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
@category Change case
|
|
33
|
+
@category Template literal
|
|
34
|
+
@category Object
|
|
35
|
+
*/
|
|
36
|
+
export type PascalCasedProperties<Value, Options extends CamelCaseOptions = {}> = Value extends Function
|
|
37
|
+
? Value
|
|
38
|
+
: Value extends Array<infer U>
|
|
39
|
+
? Value
|
|
40
|
+
: {[K in keyof Value as PascalCase<K, ApplyDefaultOptions<CamelCaseOptions, _DefaultCamelCaseOptions, Options>>]: Value[K]};
|
|
41
|
+
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import type {NonRecursiveType, ToString, IsNumberLike, ApplyDefaultOptions, MapsSetsOrArrays} from './internal/index.d.ts';
|
|
2
|
+
import type {IsAny} from './is-any.d.ts';
|
|
3
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
4
|
+
import type {GreaterThan} from './greater-than.d.ts';
|
|
5
|
+
import type {IsNever} from './is-never.d.ts';
|
|
6
|
+
import type {Sum} from './sum.d.ts';
|
|
7
|
+
import type {And} from './and.d.ts';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Paths options.
|
|
11
|
+
|
|
12
|
+
@see {@link Paths}
|
|
13
|
+
*/
|
|
14
|
+
export type PathsOptions = {
|
|
15
|
+
/**
|
|
16
|
+
The maximum depth to recurse when searching for paths. Range: 0 ~ 10.
|
|
17
|
+
|
|
18
|
+
@default 5
|
|
19
|
+
*/
|
|
20
|
+
maxRecursionDepth?: number;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Use bracket notation for array indices and numeric object keys.
|
|
24
|
+
|
|
25
|
+
@default false
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
```
|
|
29
|
+
import type {Paths} from 'type-fest';
|
|
30
|
+
|
|
31
|
+
type ArrayExample = {
|
|
32
|
+
array: ['foo'];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type A = Paths<ArrayExample, {bracketNotation: false}>;
|
|
36
|
+
//=> 'array' | 'array.0'
|
|
37
|
+
|
|
38
|
+
type B = Paths<ArrayExample, {bracketNotation: true}>;
|
|
39
|
+
//=> 'array' | 'array[0]'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
@example
|
|
43
|
+
```
|
|
44
|
+
import type {Paths} from 'type-fest';
|
|
45
|
+
|
|
46
|
+
type NumberKeyExample = {
|
|
47
|
+
1: ['foo'];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type A = Paths<NumberKeyExample, {bracketNotation: false}>;
|
|
51
|
+
//=> 1 | '1' | '1.0'
|
|
52
|
+
|
|
53
|
+
type B = Paths<NumberKeyExample, {bracketNotation: true}>;
|
|
54
|
+
//=> '[1]' | '[1][0]'
|
|
55
|
+
```
|
|
56
|
+
*/
|
|
57
|
+
bracketNotation?: boolean;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
Only include leaf paths in the output.
|
|
61
|
+
|
|
62
|
+
@default false
|
|
63
|
+
|
|
64
|
+
@example
|
|
65
|
+
```
|
|
66
|
+
import type {Paths} from 'type-fest';
|
|
67
|
+
|
|
68
|
+
type Post = {
|
|
69
|
+
id: number;
|
|
70
|
+
author: {
|
|
71
|
+
id: number;
|
|
72
|
+
name: {
|
|
73
|
+
first: string;
|
|
74
|
+
last: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type AllPaths = Paths<Post, {leavesOnly: false}>;
|
|
80
|
+
//=> 'id' | 'author' | 'author.id' | 'author.name' | 'author.name.first' | 'author.name.last'
|
|
81
|
+
|
|
82
|
+
type LeafPaths = Paths<Post, {leavesOnly: true}>;
|
|
83
|
+
//=> 'id' | 'author.id' | 'author.name.first' | 'author.name.last'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
@example
|
|
87
|
+
```
|
|
88
|
+
import type {Paths} from 'type-fest';
|
|
89
|
+
|
|
90
|
+
type ArrayExample = {
|
|
91
|
+
array: Array<{foo: string}>;
|
|
92
|
+
tuple: [string, {bar: string}];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
type AllPaths = Paths<ArrayExample, {leavesOnly: false}>;
|
|
96
|
+
//=> 'array' | 'tuple' | `array.${number}` | `array.${number}.foo` | 'tuple.0' | 'tuple.1' | 'tuple.1.bar'
|
|
97
|
+
|
|
98
|
+
type LeafPaths = Paths<ArrayExample, {leavesOnly: true}>;
|
|
99
|
+
//=> `array.${number}.foo` | 'tuple.0' | 'tuple.1.bar'
|
|
100
|
+
```
|
|
101
|
+
*/
|
|
102
|
+
leavesOnly?: boolean;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Only include paths at the specified depth. By default all paths up to {@link PathsOptions.maxRecursionDepth | `maxRecursionDepth`} are included.
|
|
106
|
+
|
|
107
|
+
Note: Depth starts at `0` for root properties.
|
|
108
|
+
|
|
109
|
+
@default number
|
|
110
|
+
|
|
111
|
+
@example
|
|
112
|
+
```
|
|
113
|
+
import type {Paths} from 'type-fest';
|
|
114
|
+
|
|
115
|
+
type Post = {
|
|
116
|
+
id: number;
|
|
117
|
+
author: {
|
|
118
|
+
id: number;
|
|
119
|
+
name: {
|
|
120
|
+
first: string;
|
|
121
|
+
last: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
type DepthZero = Paths<Post, {depth: 0}>;
|
|
127
|
+
//=> 'id' | 'author'
|
|
128
|
+
|
|
129
|
+
type DepthOne = Paths<Post, {depth: 1}>;
|
|
130
|
+
//=> 'author.id' | 'author.name'
|
|
131
|
+
|
|
132
|
+
type DepthTwo = Paths<Post, {depth: 2}>;
|
|
133
|
+
//=> 'author.name.first' | 'author.name.last'
|
|
134
|
+
|
|
135
|
+
type LeavesAtDepthOne = Paths<Post, {leavesOnly: true; depth: 1}>;
|
|
136
|
+
//=> 'author.id'
|
|
137
|
+
```
|
|
138
|
+
*/
|
|
139
|
+
depth?: number;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
type DefaultPathsOptions = {
|
|
143
|
+
maxRecursionDepth: 5;
|
|
144
|
+
bracketNotation: false;
|
|
145
|
+
leavesOnly: false;
|
|
146
|
+
depth: number;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
Generate a union of all possible paths to properties in the given object.
|
|
151
|
+
|
|
152
|
+
It also works with arrays.
|
|
153
|
+
|
|
154
|
+
Use-case: You want a type-safe way to access deeply nested properties in an object.
|
|
155
|
+
|
|
156
|
+
@example
|
|
157
|
+
```
|
|
158
|
+
import type {Paths} from 'type-fest';
|
|
159
|
+
|
|
160
|
+
type Project = {
|
|
161
|
+
filename: string;
|
|
162
|
+
listA: string[];
|
|
163
|
+
listB: [{filename: string}];
|
|
164
|
+
folder: {
|
|
165
|
+
subfolder: {
|
|
166
|
+
filename: string;
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
type ProjectPaths = Paths<Project>;
|
|
172
|
+
//=> 'filename' | 'listA' | 'listB' | 'folder' | `listA.${number}` | 'listB.0' | 'listB.0.filename' | 'folder.subfolder' | 'folder.subfolder.filename'
|
|
173
|
+
|
|
174
|
+
declare function open<Path extends ProjectPaths>(path: Path): void;
|
|
175
|
+
|
|
176
|
+
open('filename'); // Pass
|
|
177
|
+
open('folder.subfolder'); // Pass
|
|
178
|
+
open('folder.subfolder.filename'); // Pass
|
|
179
|
+
// @ts-expect-error
|
|
180
|
+
open('foo'); // TypeError
|
|
181
|
+
|
|
182
|
+
// Also works with arrays
|
|
183
|
+
open('listA.1'); // Pass
|
|
184
|
+
open('listB.0'); // Pass
|
|
185
|
+
// @ts-expect-error
|
|
186
|
+
open('listB.1'); // TypeError. Because listB only has one element.
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
@category Object
|
|
190
|
+
@category Array
|
|
191
|
+
*/
|
|
192
|
+
export type Paths<T, Options extends PathsOptions = {}> = _Paths<T, ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, Options>>;
|
|
193
|
+
|
|
194
|
+
type _Paths<T, Options extends Required<PathsOptions>, CurrentDepth extends number = 0> =
|
|
195
|
+
T extends NonRecursiveType | Exclude<MapsSetsOrArrays, UnknownArray>
|
|
196
|
+
? never
|
|
197
|
+
: IsAny<T> extends true
|
|
198
|
+
? never
|
|
199
|
+
: T extends object
|
|
200
|
+
? InternalPaths<Required<T>, Options, CurrentDepth>
|
|
201
|
+
: never;
|
|
202
|
+
|
|
203
|
+
type InternalPaths<T, Options extends Required<PathsOptions>, CurrentDepth extends number> =
|
|
204
|
+
{[Key in keyof T]: Key extends string | number // Limit `Key` to `string | number`
|
|
205
|
+
? (
|
|
206
|
+
And<Options['bracketNotation'], IsNumberLike<Key>> extends true
|
|
207
|
+
? `[${Key}]`
|
|
208
|
+
: CurrentDepth extends 0
|
|
209
|
+
// Return both `Key` and `ToString<Key>` because for number keys, like `1`, both `1` and `'1'` are valid keys.
|
|
210
|
+
? Key | ToString<Key>
|
|
211
|
+
: `.${(Key | ToString<Key>)}`
|
|
212
|
+
) extends infer TransformedKey extends string | number
|
|
213
|
+
? ((Options['leavesOnly'] extends true
|
|
214
|
+
? Options['maxRecursionDepth'] extends CurrentDepth
|
|
215
|
+
? TransformedKey
|
|
216
|
+
: IsNever<T[Key]> extends true
|
|
217
|
+
? TransformedKey
|
|
218
|
+
: T[Key] extends infer Value // For distributing `T[Key]`
|
|
219
|
+
? (Value extends readonly [] | NonRecursiveType | Exclude<MapsSetsOrArrays, UnknownArray>
|
|
220
|
+
? TransformedKey
|
|
221
|
+
: IsNever<keyof Value> extends true // Check for empty object & `unknown`, because `keyof unknown` is `never`.
|
|
222
|
+
? TransformedKey
|
|
223
|
+
: never)
|
|
224
|
+
: never // Should never happen
|
|
225
|
+
: TransformedKey
|
|
226
|
+
) extends infer _TransformedKey
|
|
227
|
+
// If `depth` is provided, the condition becomes truthy only when it matches `CurrentDepth`.
|
|
228
|
+
// Otherwise, since `depth` defaults to `number`, the condition is always truthy, returning paths at all depths.
|
|
229
|
+
? CurrentDepth extends Options['depth']
|
|
230
|
+
? _TransformedKey
|
|
231
|
+
: never
|
|
232
|
+
: never)
|
|
233
|
+
// Recursively generate paths for the current key
|
|
234
|
+
| (GreaterThan<Options['maxRecursionDepth'], CurrentDepth> extends true // Limit the depth to prevent infinite recursion
|
|
235
|
+
? `${TransformedKey}${_Paths<T[Key], Options, Sum<CurrentDepth, 1>> & (string | number)}`
|
|
236
|
+
: never)
|
|
237
|
+
: never
|
|
238
|
+
: never
|
|
239
|
+
}[keyof T & (T extends UnknownArray ? number : unknown)];
|
|
240
|
+
|
|
241
|
+
export {};
|