@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,120 @@
|
|
|
1
|
+
import type {IsEqual} from './is-equal.d.ts';
|
|
2
|
+
import type {ConditionalExcept} from './conditional-except.d.ts';
|
|
3
|
+
import type {ConditionalSimplifyDeep} from './conditional-simplify-deep.d.ts';
|
|
4
|
+
import type {UnknownRecord} from './unknown-record.d.ts';
|
|
5
|
+
import type {EmptyObject} from './empty-object.d.ts';
|
|
6
|
+
import type {ApplyDefaultOptions, IsPlainObject} from './internal/index.d.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
Used to mark properties that should be excluded.
|
|
10
|
+
*/
|
|
11
|
+
declare const conditionalPickDeepSymbol: unique symbol;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
Assert the condition according to the {@link ConditionalPickDeepOptions.condition|condition} option.
|
|
15
|
+
*/
|
|
16
|
+
type AssertCondition<Type, Condition, Options extends ConditionalPickDeepOptions> = Options['condition'] extends 'equality'
|
|
17
|
+
? IsEqual<Type, Condition>
|
|
18
|
+
: Type extends Condition
|
|
19
|
+
? true
|
|
20
|
+
: false;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
ConditionalPickDeep options.
|
|
24
|
+
|
|
25
|
+
@see {@link ConditionalPickDeep}
|
|
26
|
+
*/
|
|
27
|
+
export type ConditionalPickDeepOptions = {
|
|
28
|
+
/**
|
|
29
|
+
The condition assertion mode.
|
|
30
|
+
|
|
31
|
+
@default 'extends'
|
|
32
|
+
*/
|
|
33
|
+
condition?: 'extends' | 'equality';
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type DefaultConditionalPickDeepOptions = {
|
|
37
|
+
condition: 'extends';
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
Pick keys recursively from the shape that matches the given condition.
|
|
42
|
+
|
|
43
|
+
@see {@link ConditionalPick}
|
|
44
|
+
|
|
45
|
+
@example
|
|
46
|
+
```
|
|
47
|
+
import type {ConditionalPickDeep} from 'type-fest';
|
|
48
|
+
|
|
49
|
+
type Example = {
|
|
50
|
+
a: string;
|
|
51
|
+
b: string | boolean;
|
|
52
|
+
c: {
|
|
53
|
+
d: string;
|
|
54
|
+
e: {
|
|
55
|
+
f?: string;
|
|
56
|
+
g?: boolean;
|
|
57
|
+
h: string | boolean;
|
|
58
|
+
i: boolean | bigint;
|
|
59
|
+
};
|
|
60
|
+
j: boolean;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type StringPick = ConditionalPickDeep<Example, string>;
|
|
65
|
+
//=> {a: string; c: {d: string}}
|
|
66
|
+
|
|
67
|
+
type StringPickOptional = ConditionalPickDeep<Example, string | undefined>;
|
|
68
|
+
//=> {a: string; c: {d: string; e: {f?: string}}}
|
|
69
|
+
|
|
70
|
+
type StringPickOptionalOnly = ConditionalPickDeep<Example, string | undefined, {condition: 'equality'}>;
|
|
71
|
+
//=> {c: {e: {f?: string}}}
|
|
72
|
+
|
|
73
|
+
type BooleanPick = ConditionalPickDeep<Example, boolean | undefined>;
|
|
74
|
+
//=> {c: {e: {g?: boolean}; j: boolean}}
|
|
75
|
+
|
|
76
|
+
type NumberPick = ConditionalPickDeep<Example, number>;
|
|
77
|
+
//=> {}
|
|
78
|
+
|
|
79
|
+
type StringOrBooleanPick = ConditionalPickDeep<Example, string | boolean>;
|
|
80
|
+
//=> {
|
|
81
|
+
// a: string;
|
|
82
|
+
// b: string | boolean;
|
|
83
|
+
// c: {
|
|
84
|
+
// d: string;
|
|
85
|
+
// e: {
|
|
86
|
+
// h: string | boolean;
|
|
87
|
+
// };
|
|
88
|
+
// j: boolean;
|
|
89
|
+
// };
|
|
90
|
+
// }
|
|
91
|
+
|
|
92
|
+
type StringOrBooleanPickOnly = ConditionalPickDeep<Example, string | boolean, {condition: 'equality'}>;
|
|
93
|
+
//=> {b: string | boolean; c: {e: {h: string | boolean}}}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
@category Object
|
|
97
|
+
*/
|
|
98
|
+
export type ConditionalPickDeep<
|
|
99
|
+
Type,
|
|
100
|
+
Condition,
|
|
101
|
+
Options extends ConditionalPickDeepOptions = {},
|
|
102
|
+
> = _ConditionalPickDeep<
|
|
103
|
+
Type,
|
|
104
|
+
Condition,
|
|
105
|
+
ApplyDefaultOptions<ConditionalPickDeepOptions, DefaultConditionalPickDeepOptions, Options>
|
|
106
|
+
>;
|
|
107
|
+
|
|
108
|
+
type _ConditionalPickDeep<
|
|
109
|
+
Type,
|
|
110
|
+
Condition,
|
|
111
|
+
Options extends Required<ConditionalPickDeepOptions>,
|
|
112
|
+
> = ConditionalSimplifyDeep<ConditionalExcept<{
|
|
113
|
+
[Key in keyof Type]: AssertCondition<Type[Key], Condition, Options> extends true
|
|
114
|
+
? Type[Key]
|
|
115
|
+
: IsPlainObject<Type[Key]> extends true
|
|
116
|
+
? _ConditionalPickDeep<Type[Key], Condition, Options>
|
|
117
|
+
: typeof conditionalPickDeepSymbol;
|
|
118
|
+
}, (typeof conditionalPickDeepSymbol | undefined) | EmptyObject>, never, UnknownRecord>;
|
|
119
|
+
|
|
120
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type {ConditionalKeys} from './conditional-keys.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Pick keys from the shape that matches the given `Condition`.
|
|
5
|
+
|
|
6
|
+
This is useful when you want to create a new type from a specific subset of an existing type. For example, you might want to pick all the primitive properties from a class and form a new automatically derived type.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {Primitive, ConditionalPick} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
class Awesome {
|
|
13
|
+
constructor(public name: string, public successes: number, public failures: bigint) {}
|
|
14
|
+
|
|
15
|
+
run() {
|
|
16
|
+
// do something
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type PickPrimitivesFromAwesome = ConditionalPick<Awesome, Primitive>;
|
|
21
|
+
//=> {name: string; successes: number; failures: bigint}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
@example
|
|
25
|
+
```
|
|
26
|
+
import type {ConditionalPick} from 'type-fest';
|
|
27
|
+
|
|
28
|
+
type Example = {
|
|
29
|
+
a: string;
|
|
30
|
+
b: string | number;
|
|
31
|
+
c: () => void;
|
|
32
|
+
d: {};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type StringKeysOnly = ConditionalPick<Example, string>;
|
|
36
|
+
//=> {a: string}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
@category Object
|
|
40
|
+
*/
|
|
41
|
+
export type ConditionalPick<Base, Condition> = Pick<
|
|
42
|
+
Base,
|
|
43
|
+
ConditionalKeys<Base, Condition>
|
|
44
|
+
>;
|
|
45
|
+
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Recursively simplifies a type while including and/or excluding certain types from being simplified.
|
|
3
|
+
|
|
4
|
+
@example
|
|
5
|
+
```
|
|
6
|
+
import type {ConditionalSimplifyDeep} from 'type-fest';
|
|
7
|
+
|
|
8
|
+
type TypeA = {
|
|
9
|
+
foo: {
|
|
10
|
+
a: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type TypeB = {
|
|
15
|
+
foo: {
|
|
16
|
+
b: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type SimplifyDeepTypeAB = ConditionalSimplifyDeep<TypeA & TypeB, never, object>;
|
|
21
|
+
//=> {foo: {a: string; b: string}}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
@example
|
|
25
|
+
```
|
|
26
|
+
import type {ConditionalSimplifyDeep} from 'type-fest';
|
|
27
|
+
|
|
28
|
+
type SomeComplexType1 = {
|
|
29
|
+
a1: string;
|
|
30
|
+
b1: number;
|
|
31
|
+
c1: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type SomeComplexType2 = {
|
|
35
|
+
a2: string;
|
|
36
|
+
b2: number;
|
|
37
|
+
c2: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type TypeA = {
|
|
41
|
+
foo: {
|
|
42
|
+
a: string;
|
|
43
|
+
complexType: SomeComplexType1;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type TypeB = {
|
|
48
|
+
foo: {
|
|
49
|
+
b: string;
|
|
50
|
+
complexType: SomeComplexType2;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type SimplifyDeepTypeAB = ConditionalSimplifyDeep<TypeA & TypeB, SomeComplexType1 | SomeComplexType2, object>;
|
|
55
|
+
//=> {
|
|
56
|
+
// foo: {
|
|
57
|
+
// a: string;
|
|
58
|
+
// complexType: SomeComplexType1 & SomeComplexType2;
|
|
59
|
+
// b: string;
|
|
60
|
+
// };
|
|
61
|
+
// }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
@see {@link SimplifyDeep}
|
|
65
|
+
@category Object
|
|
66
|
+
*/
|
|
67
|
+
export type ConditionalSimplifyDeep<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
|
|
68
|
+
? Type
|
|
69
|
+
: Type extends IncludeType
|
|
70
|
+
? {[TypeKey in keyof Type]: ConditionalSimplifyDeep<Type[TypeKey], ExcludeType, IncludeType>}
|
|
71
|
+
: Type;
|
|
72
|
+
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Simplifies a type while including and/or excluding certain types from being simplified.
|
|
3
|
+
|
|
4
|
+
Useful to improve type hints shown in editors. And also to transform an `interface` into a `type` to aid with assignability.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {ConditionalSimplify} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type TypeA = {
|
|
11
|
+
a: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type TypeB = {
|
|
15
|
+
b: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type TypeAB = TypeA & TypeB;
|
|
19
|
+
//=> TypeA & TypeB
|
|
20
|
+
|
|
21
|
+
type SimplifyTypeAB = ConditionalSimplify<TypeAB, never, object>;
|
|
22
|
+
//=> {a: string; b: string}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
```
|
|
27
|
+
import type {ConditionalSimplify} from 'type-fest';
|
|
28
|
+
|
|
29
|
+
type Simplify<T> = ConditionalSimplify<T, Set<unknown> | Map<unknown, unknown> | unknown[], object>;
|
|
30
|
+
|
|
31
|
+
type A = Simplify<Set<number> & Set<string>>;
|
|
32
|
+
//=> Set<number> & Set<string>
|
|
33
|
+
|
|
34
|
+
type B = Simplify<Map<number, number> & Map<string, string>>;
|
|
35
|
+
//=> Map<number, number> & Map<string, string>
|
|
36
|
+
|
|
37
|
+
type C = Simplify<{a: number} & {b: string}>;
|
|
38
|
+
//=> {a: number; b: string}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
@see {@link ConditionalSimplifyDeep}
|
|
42
|
+
@category Object
|
|
43
|
+
*/
|
|
44
|
+
export type ConditionalSimplify<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
|
|
45
|
+
? Type
|
|
46
|
+
: Type extends IncludeType
|
|
47
|
+
? {[TypeKey in keyof Type]: Type[TypeKey]}
|
|
48
|
+
: Type;
|
|
49
|
+
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type {ApplyDefaultOptions, AsciiPunctuation, StartsWith} from './internal/index.d.ts';
|
|
2
|
+
import type {IsStringLiteral} from './is-literal.d.ts';
|
|
3
|
+
import type {Merge} from './merge.d.ts';
|
|
4
|
+
import type {RemovePrefix} from './remove-prefix.d.ts';
|
|
5
|
+
import type {_DefaultWordsOptions, Words, WordsOptions} from './words.d.ts';
|
|
6
|
+
|
|
7
|
+
export type _DefaultDelimiterCaseOptions = Merge<_DefaultWordsOptions, {splitOnNumbers: false}>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Convert an array of words to delimiter case starting with a delimiter with input capitalization.
|
|
11
|
+
*/
|
|
12
|
+
type DelimiterCaseFromArray<
|
|
13
|
+
Words extends string[],
|
|
14
|
+
Delimiter extends string,
|
|
15
|
+
OutputString extends string = '',
|
|
16
|
+
> = Words extends [
|
|
17
|
+
infer FirstWord extends string,
|
|
18
|
+
...infer RemainingWords extends string[],
|
|
19
|
+
]
|
|
20
|
+
? DelimiterCaseFromArray<RemainingWords, Delimiter, `${OutputString}${
|
|
21
|
+
StartsWith<FirstWord, AsciiPunctuation> extends true ? '' : Delimiter
|
|
22
|
+
}${FirstWord}`>
|
|
23
|
+
: OutputString;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
Convert a string literal to a custom string delimiter casing.
|
|
27
|
+
|
|
28
|
+
This can be useful when, for example, converting a camel-cased object property to an oddly cased one.
|
|
29
|
+
|
|
30
|
+
@see {@link KebabCase}
|
|
31
|
+
@see {@link SnakeCase}
|
|
32
|
+
|
|
33
|
+
@example
|
|
34
|
+
```
|
|
35
|
+
import type {DelimiterCase} from 'type-fest';
|
|
36
|
+
|
|
37
|
+
// Simple
|
|
38
|
+
|
|
39
|
+
const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar';
|
|
40
|
+
const someVariableNoSplitOnNumbers: DelimiterCase<'p2pNetwork', '#', {splitOnNumbers: false}> = 'p2p#network';
|
|
41
|
+
|
|
42
|
+
// Advanced
|
|
43
|
+
|
|
44
|
+
type OddlyCasedProperties<T> = {
|
|
45
|
+
[K in keyof T as DelimiterCase<K, '#'>]: T[K]
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
type SomeOptions = {
|
|
49
|
+
dryRun: boolean;
|
|
50
|
+
includeFile: string;
|
|
51
|
+
foo: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const rawCliOptions: OddlyCasedProperties<SomeOptions> = {
|
|
55
|
+
'dry#run': true,
|
|
56
|
+
'include#file': 'bar.js',
|
|
57
|
+
foo: 123,
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
@category Change case
|
|
62
|
+
@category Template literal
|
|
63
|
+
*/
|
|
64
|
+
export type DelimiterCase<
|
|
65
|
+
Value,
|
|
66
|
+
Delimiter extends string,
|
|
67
|
+
Options extends WordsOptions = {},
|
|
68
|
+
> = Value extends string
|
|
69
|
+
? IsStringLiteral<Value> extends false
|
|
70
|
+
? Value
|
|
71
|
+
: Lowercase<RemovePrefix<DelimiterCaseFromArray<
|
|
72
|
+
Words<Value, ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>,
|
|
73
|
+
Delimiter
|
|
74
|
+
>, string, {strict: false}>>
|
|
75
|
+
: Value;
|
|
76
|
+
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type {_DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions, NonRecursiveType} from './internal/index.d.ts';
|
|
3
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
4
|
+
import type {WordsOptions} from './words.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Convert object properties to delimiter case recursively.
|
|
8
|
+
|
|
9
|
+
This can be useful when, for example, converting some API types from a different style.
|
|
10
|
+
|
|
11
|
+
@see {@link DelimiterCase}
|
|
12
|
+
@see {@link DelimiterCasedProperties}
|
|
13
|
+
|
|
14
|
+
@example
|
|
15
|
+
```
|
|
16
|
+
import type {DelimiterCasedPropertiesDeep} from 'type-fest';
|
|
17
|
+
|
|
18
|
+
type User = {
|
|
19
|
+
userId: number;
|
|
20
|
+
userName: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type UserWithFriends = {
|
|
24
|
+
userInfo: User;
|
|
25
|
+
userFriends: User[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const result: DelimiterCasedPropertiesDeep<UserWithFriends, '-'> = {
|
|
29
|
+
'user-info': {
|
|
30
|
+
'user-id': 1,
|
|
31
|
+
'user-name': 'Tom',
|
|
32
|
+
},
|
|
33
|
+
'user-friends': [
|
|
34
|
+
{
|
|
35
|
+
'user-id': 2,
|
|
36
|
+
'user-name': 'Jerry',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
'user-id': 3,
|
|
40
|
+
'user-name': 'Spike',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const splitOnNumbers: DelimiterCasedPropertiesDeep<{line1: {line2: [{line3: string}]}}, '-', {splitOnNumbers: true}> = {
|
|
46
|
+
'line-1': {
|
|
47
|
+
'line-2': [
|
|
48
|
+
{
|
|
49
|
+
'line-3': 'string',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
@category Change case
|
|
57
|
+
@category Template literal
|
|
58
|
+
@category Object
|
|
59
|
+
*/
|
|
60
|
+
export type DelimiterCasedPropertiesDeep<
|
|
61
|
+
Value,
|
|
62
|
+
Delimiter extends string,
|
|
63
|
+
Options extends WordsOptions = {},
|
|
64
|
+
> = _DelimiterCasedPropertiesDeep<Value, Delimiter, ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>;
|
|
65
|
+
|
|
66
|
+
type _DelimiterCasedPropertiesDeep<
|
|
67
|
+
Value,
|
|
68
|
+
Delimiter extends string,
|
|
69
|
+
Options extends Required<WordsOptions>,
|
|
70
|
+
> = Value extends NonRecursiveType
|
|
71
|
+
? Value
|
|
72
|
+
: Value extends UnknownArray
|
|
73
|
+
? DelimiterCasedPropertiesArrayDeep<Value, Delimiter, Options>
|
|
74
|
+
: Value extends Set<infer U>
|
|
75
|
+
? Set<_DelimiterCasedPropertiesDeep<U, Delimiter, Options>>
|
|
76
|
+
: Value extends object
|
|
77
|
+
? {
|
|
78
|
+
[K in keyof Value as DelimiterCase<K, Delimiter, Options>]:
|
|
79
|
+
_DelimiterCasedPropertiesDeep<Value[K], Delimiter, Options>
|
|
80
|
+
}
|
|
81
|
+
: Value;
|
|
82
|
+
|
|
83
|
+
// This is a copy of CamelCasedPropertiesArrayDeep (see: camel-cased-properties-deep.d.ts).
|
|
84
|
+
// These types should be kept in sync.
|
|
85
|
+
type DelimiterCasedPropertiesArrayDeep<
|
|
86
|
+
Value extends UnknownArray,
|
|
87
|
+
Delimiter extends string,
|
|
88
|
+
Options extends Required<WordsOptions>,
|
|
89
|
+
> = Value extends []
|
|
90
|
+
? []
|
|
91
|
+
// Trailing spread array
|
|
92
|
+
: Value extends [infer U, ...infer V]
|
|
93
|
+
? [_DelimiterCasedPropertiesDeep<U, Delimiter, Options>, ..._DelimiterCasedPropertiesDeep<V, Delimiter, Options>]
|
|
94
|
+
: Value extends readonly [infer U, ...infer V]
|
|
95
|
+
? readonly [_DelimiterCasedPropertiesDeep<U, Delimiter, Options>, ..._DelimiterCasedPropertiesDeep<V, Delimiter, Options>]
|
|
96
|
+
// Leading spread array
|
|
97
|
+
: Value extends [...infer U, infer V]
|
|
98
|
+
? [..._DelimiterCasedPropertiesDeep<U, Delimiter, Options>, _DelimiterCasedPropertiesDeep<V, Delimiter, Options>]
|
|
99
|
+
: Value extends readonly [...infer U, infer V]
|
|
100
|
+
? readonly [..._DelimiterCasedPropertiesDeep<U, Delimiter, Options>, _DelimiterCasedPropertiesDeep<V, Delimiter, Options>]
|
|
101
|
+
// Array
|
|
102
|
+
: Value extends Array<infer U>
|
|
103
|
+
? Array<_DelimiterCasedPropertiesDeep<U, Delimiter, Options>>
|
|
104
|
+
: Value extends ReadonlyArray<infer U>
|
|
105
|
+
? ReadonlyArray<_DelimiterCasedPropertiesDeep<U, Delimiter, Options>>
|
|
106
|
+
: never;
|
|
107
|
+
|
|
108
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type {_DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
3
|
+
import type {WordsOptions} from './words.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Convert object properties to delimiter 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 DelimiterCase}
|
|
11
|
+
@see {@link DelimiterCasedPropertiesDeep}
|
|
12
|
+
|
|
13
|
+
@example
|
|
14
|
+
```
|
|
15
|
+
import type {DelimiterCasedProperties} from 'type-fest';
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
userId: number;
|
|
19
|
+
userName: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const result: DelimiterCasedProperties<User, '-'> = {
|
|
23
|
+
'user-id': 1,
|
|
24
|
+
'user-name': 'Tom',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const splitOnNumbers: DelimiterCasedProperties<{line1: string}, '-', {splitOnNumbers: true}> = {
|
|
28
|
+
'line-1': 'string',
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
@category Change case
|
|
33
|
+
@category Template literal
|
|
34
|
+
@category Object
|
|
35
|
+
*/
|
|
36
|
+
export type DelimiterCasedProperties<
|
|
37
|
+
Value,
|
|
38
|
+
Delimiter extends string,
|
|
39
|
+
Options extends WordsOptions = {},
|
|
40
|
+
> = Value extends Function
|
|
41
|
+
? Value
|
|
42
|
+
: Value extends Array<infer U>
|
|
43
|
+
? Value
|
|
44
|
+
: {[K in keyof Value as
|
|
45
|
+
DelimiterCase<K, Delimiter, ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>
|
|
46
|
+
]: Value[K]};
|
|
47
|
+
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type {KeysOfUnion} from './keys-of-union.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Omits keys from a type, distributing the operation over a union.
|
|
5
|
+
|
|
6
|
+
TypeScript's `Omit` doesn't distribute over unions, leading to the erasure of unique properties from union members when omitting keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Omit. Essentially, using `Omit` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
type A = {
|
|
12
|
+
discriminant: 'A';
|
|
13
|
+
foo: string;
|
|
14
|
+
a: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type B = {
|
|
18
|
+
discriminant: 'B';
|
|
19
|
+
foo: string;
|
|
20
|
+
b: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Union = A | B;
|
|
24
|
+
|
|
25
|
+
type OmittedUnion = Omit<Union, 'foo'>;
|
|
26
|
+
//=> {discriminant: 'A' | 'B'}
|
|
27
|
+
|
|
28
|
+
declare const omittedUnion: OmittedUnion;
|
|
29
|
+
|
|
30
|
+
if (omittedUnion.discriminant === 'A') {
|
|
31
|
+
// We would like to narrow `omittedUnion`'s type
|
|
32
|
+
// to `A` here, but we can't because `Omit`
|
|
33
|
+
// doesn't distribute over unions.
|
|
34
|
+
|
|
35
|
+
// @ts-expect-error
|
|
36
|
+
const aValue = omittedUnion.a;
|
|
37
|
+
// Error: `a` is not a property of `{discriminant: 'A' | 'B'}`
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
While `Except` solves this problem, it restricts the keys you can omit to the ones that are present in **ALL** union members, where `DistributedOmit` allows you to omit keys that are present in **ANY** union member.
|
|
42
|
+
|
|
43
|
+
@example
|
|
44
|
+
```
|
|
45
|
+
import type {DistributedOmit} from 'type-fest';
|
|
46
|
+
|
|
47
|
+
type A = {
|
|
48
|
+
discriminant: 'A';
|
|
49
|
+
foo: string;
|
|
50
|
+
a: number;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
type B = {
|
|
54
|
+
discriminant: 'B';
|
|
55
|
+
foo: string;
|
|
56
|
+
bar: string;
|
|
57
|
+
b: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
type C = {
|
|
61
|
+
discriminant: 'C';
|
|
62
|
+
bar: string;
|
|
63
|
+
c: boolean;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Notice that `foo` exists in `A` and `B`, but not in `C`, and
|
|
67
|
+
// `bar` exists in `B` and `C`, but not in `A`.
|
|
68
|
+
|
|
69
|
+
type Union = A | B | C;
|
|
70
|
+
|
|
71
|
+
type OmittedUnion = DistributedOmit<Union, 'foo' | 'bar'>;
|
|
72
|
+
|
|
73
|
+
declare const omittedUnion: OmittedUnion;
|
|
74
|
+
|
|
75
|
+
if (omittedUnion.discriminant === 'A') {
|
|
76
|
+
const aValue = omittedUnion.a;
|
|
77
|
+
// OK
|
|
78
|
+
|
|
79
|
+
// @ts-expect-error
|
|
80
|
+
const fooValue = omittedUnion.foo;
|
|
81
|
+
// Error: `foo` is not a property of `{discriminant: 'A'; a: string}`
|
|
82
|
+
|
|
83
|
+
// @ts-expect-error
|
|
84
|
+
const barValue = omittedUnion.bar;
|
|
85
|
+
// Error: `bar` is not a property of `{discriminant: 'A'; a: string}`
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
@category Object
|
|
90
|
+
*/
|
|
91
|
+
export type DistributedOmit<ObjectType, KeyType extends KeysOfUnion<ObjectType>> =
|
|
92
|
+
ObjectType extends unknown
|
|
93
|
+
? Omit<ObjectType, KeyType>
|
|
94
|
+
: never;
|
|
95
|
+
|
|
96
|
+
export {};
|