@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,117 @@
|
|
|
1
|
+
import type {ConditionalSimplifyDeep} from './conditional-simplify-deep.d.ts';
|
|
2
|
+
import type {MapsSetsOrArrays, NonRecursiveType} from './internal/index.d.ts';
|
|
3
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Deeply simplifies an object type.
|
|
7
|
+
|
|
8
|
+
You can exclude certain types from being simplified by providing them in the second generic `ExcludeType`.
|
|
9
|
+
|
|
10
|
+
Useful to flatten the type output to improve type hints shown in editors.
|
|
11
|
+
|
|
12
|
+
@example
|
|
13
|
+
```
|
|
14
|
+
import type {SimplifyDeep} from 'type-fest';
|
|
15
|
+
|
|
16
|
+
type PositionX = {
|
|
17
|
+
left: number;
|
|
18
|
+
right: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type PositionY = {
|
|
22
|
+
top: number;
|
|
23
|
+
bottom: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type Properties1 = {
|
|
27
|
+
height: number;
|
|
28
|
+
position: PositionY;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type Properties2 = {
|
|
32
|
+
width: number;
|
|
33
|
+
position: PositionX;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type Properties = Properties1 & Properties2;
|
|
37
|
+
// In your editor, hovering over `Props` will show the following:
|
|
38
|
+
//
|
|
39
|
+
// type Properties = Properties1 & Properties2;
|
|
40
|
+
|
|
41
|
+
type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2>;
|
|
42
|
+
// But if wrapped in SimplifyDeep, hovering over `SimplifyDeepProperties` will show a flattened object with all the properties:
|
|
43
|
+
//
|
|
44
|
+
// SimplifyDeepProperties = {
|
|
45
|
+
// height: number;
|
|
46
|
+
// width: number;
|
|
47
|
+
// position: {
|
|
48
|
+
// top: number;
|
|
49
|
+
// bottom: number;
|
|
50
|
+
// left: number;
|
|
51
|
+
// right: number;
|
|
52
|
+
// };
|
|
53
|
+
// };
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
@example
|
|
57
|
+
```
|
|
58
|
+
import type {SimplifyDeep} from 'type-fest';
|
|
59
|
+
|
|
60
|
+
// A complex type that you don't want or need to simplify
|
|
61
|
+
type ComplexType = {
|
|
62
|
+
a: string;
|
|
63
|
+
b: 'b';
|
|
64
|
+
c: number;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
type PositionX = {
|
|
68
|
+
left: number;
|
|
69
|
+
right: number;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type PositionY = {
|
|
73
|
+
top: number;
|
|
74
|
+
bottom: number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// You want to simplify all other types
|
|
78
|
+
type Properties1 = {
|
|
79
|
+
height: number;
|
|
80
|
+
position: PositionY;
|
|
81
|
+
foo: ComplexType;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
type Properties2 = {
|
|
85
|
+
width: number;
|
|
86
|
+
position: PositionX;
|
|
87
|
+
foo: ComplexType;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2, ComplexType>;
|
|
91
|
+
// If wrapped in `SimplifyDeep` and set `ComplexType` to exclude, hovering over `SimplifyDeepProperties` will
|
|
92
|
+
// show a flattened object with all the properties except `ComplexType`:
|
|
93
|
+
//
|
|
94
|
+
// SimplifyDeepProperties = {
|
|
95
|
+
// height: number;
|
|
96
|
+
// width: number;
|
|
97
|
+
// position: {
|
|
98
|
+
// top: number;
|
|
99
|
+
// bottom: number;
|
|
100
|
+
// left: number;
|
|
101
|
+
// right: number;
|
|
102
|
+
// };
|
|
103
|
+
// foo: ComplexType;
|
|
104
|
+
// };
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
@see {@link Simplify}
|
|
108
|
+
@category Object
|
|
109
|
+
*/
|
|
110
|
+
export type SimplifyDeep<Type, ExcludeType = never> =
|
|
111
|
+
ConditionalSimplifyDeep<
|
|
112
|
+
Type,
|
|
113
|
+
ExcludeType | NonRecursiveType | Exclude<MapsSetsOrArrays, UnknownArray>,
|
|
114
|
+
object
|
|
115
|
+
>;
|
|
116
|
+
|
|
117
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
|
3
|
+
|
|
4
|
+
@example
|
|
5
|
+
```
|
|
6
|
+
import type {Simplify} from 'type-fest';
|
|
7
|
+
|
|
8
|
+
type PositionProps = {
|
|
9
|
+
top: number;
|
|
10
|
+
left: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type SizeProps = {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// In your editor, hovering over `Props` will show a flattened object with all the properties.
|
|
19
|
+
type Props = Simplify<PositionProps & SizeProps>;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
|
|
23
|
+
|
|
24
|
+
If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
|
|
25
|
+
|
|
26
|
+
@example
|
|
27
|
+
```
|
|
28
|
+
import type {Simplify} from 'type-fest';
|
|
29
|
+
|
|
30
|
+
interface SomeInterface {
|
|
31
|
+
foo: number;
|
|
32
|
+
bar?: string;
|
|
33
|
+
baz: number | undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type SomeType = {
|
|
37
|
+
foo: number;
|
|
38
|
+
bar?: string;
|
|
39
|
+
baz: number | undefined;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const literal = {foo: 123, bar: 'hello', baz: 456};
|
|
43
|
+
const someType: SomeType = literal;
|
|
44
|
+
const someInterface: SomeInterface = literal;
|
|
45
|
+
|
|
46
|
+
declare function fn(object: Record<string, unknown>): void;
|
|
47
|
+
|
|
48
|
+
fn(literal); // Good: literal object type is sealed
|
|
49
|
+
fn(someType); // Good: type is sealed
|
|
50
|
+
// @ts-expect-error
|
|
51
|
+
fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
|
|
52
|
+
fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
@link https://github.com/microsoft/TypeScript/issues/15300
|
|
56
|
+
@see {@link SimplifyDeep}
|
|
57
|
+
@category Object
|
|
58
|
+
*/
|
|
59
|
+
export type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|
|
60
|
+
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type {IsEmptyObject} from './empty-object.d.ts';
|
|
2
|
+
import type {If} from './if.d.ts';
|
|
3
|
+
import type {IsUnion} from './is-union.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Create a type that only accepts an object with a single key.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {SingleKeyObject} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
declare function someFunction<T>(parameter: SingleKeyObject<T>): void;
|
|
13
|
+
|
|
14
|
+
someFunction({value: true});
|
|
15
|
+
|
|
16
|
+
// @ts-expect-error
|
|
17
|
+
someFunction({value: true, otherKey: true});
|
|
18
|
+
// Error: Argument of type '{value: boolean; otherKey: boolean}' is not assignable to parameter of type 'never'.ts(2345)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
@category Object
|
|
22
|
+
*/
|
|
23
|
+
export type SingleKeyObject<ObjectType> =
|
|
24
|
+
IsUnion<keyof ObjectType> extends true
|
|
25
|
+
? never
|
|
26
|
+
: If<IsEmptyObject<ObjectType>, never, ObjectType>;
|
|
27
|
+
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
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 a string literal to snake-case.
|
|
7
|
+
|
|
8
|
+
This can be useful when, for example, converting a camel-cased object property to a snake-cased SQL column name.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
```
|
|
12
|
+
import type {SnakeCase} from 'type-fest';
|
|
13
|
+
|
|
14
|
+
// Simple
|
|
15
|
+
|
|
16
|
+
const someVariable: SnakeCase<'fooBar'> = 'foo_bar';
|
|
17
|
+
const noSplitOnNumbers: SnakeCase<'p2pNetwork'> = 'p2p_network';
|
|
18
|
+
const splitOnNumbers: SnakeCase<'p2pNetwork', {splitOnNumbers: true}> = 'p_2_p_network';
|
|
19
|
+
|
|
20
|
+
// Advanced
|
|
21
|
+
|
|
22
|
+
type SnakeCasedProperties<T> = {
|
|
23
|
+
[K in keyof T as SnakeCase<K>]: T[K]
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type ModelProps = {
|
|
27
|
+
isHappy: boolean;
|
|
28
|
+
fullFamilyName: string;
|
|
29
|
+
foo: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const dbResult: SnakeCasedProperties<ModelProps> = {
|
|
33
|
+
'is_happy': true,
|
|
34
|
+
'full_family_name': 'Carla Smith',
|
|
35
|
+
foo: 123,
|
|
36
|
+
};
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
@category Change case
|
|
40
|
+
@category Template literal
|
|
41
|
+
*/
|
|
42
|
+
export type SnakeCase<
|
|
43
|
+
Value,
|
|
44
|
+
Options extends WordsOptions = {},
|
|
45
|
+
> = DelimiterCase<Value, '_', ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>;
|
|
46
|
+
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type {_DefaultDelimiterCaseOptions} from './delimiter-case.d.ts';
|
|
2
|
+
import type {DelimiterCasedPropertiesDeep} from './delimiter-cased-properties-deep.d.ts';
|
|
3
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
4
|
+
import type {WordsOptions} from './words.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Convert object properties to snake case recursively.
|
|
8
|
+
|
|
9
|
+
This can be useful when, for example, converting some API types from a different style.
|
|
10
|
+
|
|
11
|
+
@see {@link SnakeCase}
|
|
12
|
+
@see {@link SnakeCasedProperties}
|
|
13
|
+
|
|
14
|
+
@example
|
|
15
|
+
```
|
|
16
|
+
import type {SnakeCasedPropertiesDeep} 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: SnakeCasedPropertiesDeep<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: SnakeCasedPropertiesDeep<{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 SnakeCasedPropertiesDeep<
|
|
61
|
+
Value,
|
|
62
|
+
Options extends WordsOptions = {},
|
|
63
|
+
> = DelimiterCasedPropertiesDeep<Value, '_', ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>;
|
|
64
|
+
|
|
65
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type {_DefaultDelimiterCaseOptions} from './delimiter-case.d.ts';
|
|
2
|
+
import type {DelimiterCasedProperties} from './delimiter-cased-properties.d.ts';
|
|
3
|
+
import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
4
|
+
import type {WordsOptions} from './words.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Convert object properties to snake case but not recursively.
|
|
8
|
+
|
|
9
|
+
This can be useful when, for example, converting some API types from a different style.
|
|
10
|
+
|
|
11
|
+
@see {@link SnakeCase}
|
|
12
|
+
@see {@link SnakeCasedPropertiesDeep}
|
|
13
|
+
|
|
14
|
+
@example
|
|
15
|
+
```
|
|
16
|
+
import type {SnakeCasedProperties} from 'type-fest';
|
|
17
|
+
|
|
18
|
+
type User = {
|
|
19
|
+
userId: number;
|
|
20
|
+
userName: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const result: SnakeCasedProperties<User> = {
|
|
24
|
+
user_id: 1,
|
|
25
|
+
user_name: 'Tom',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const splitOnNumbers: SnakeCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
|
|
29
|
+
'line_1': 'string',
|
|
30
|
+
};
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
@category Change case
|
|
34
|
+
@category Template literal
|
|
35
|
+
@category Object
|
|
36
|
+
*/
|
|
37
|
+
export type SnakeCasedProperties<
|
|
38
|
+
Value,
|
|
39
|
+
Options extends WordsOptions = {},
|
|
40
|
+
> = DelimiterCasedProperties<Value, '_', ApplyDefaultOptions<WordsOptions, _DefaultDelimiterCaseOptions, Options>>;
|
|
41
|
+
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions} from './internal/object.d.ts';
|
|
3
|
+
import type {IsOptionalKeyOf} from './is-optional-key-of.d.ts';
|
|
4
|
+
import type {IsArrayReadonly} from './internal/array.d.ts';
|
|
5
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
6
|
+
import type {If} from './if.d.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
{@link SplitOnRestElement} options.
|
|
10
|
+
*/
|
|
11
|
+
type SplitOnRestElementOptions = {
|
|
12
|
+
/**
|
|
13
|
+
Whether to preserve the optional modifier (`?`).
|
|
14
|
+
|
|
15
|
+
- When set to `true`, the optional modifiers are preserved as-is. For example:
|
|
16
|
+
`SplitOnRestElement<[number, string?, ...boolean[]], {preserveOptionalModifier: true}>` returns `[[number, string?], boolean[], []]`.
|
|
17
|
+
|
|
18
|
+
- When set to `false`, optional elements like `T?` are transformed to `T | undefined` or simply `T` depending on the `exactOptionalPropertyTypes` compiler option. For example:
|
|
19
|
+
- With `exactOptionalPropertyTypes` enabled: `SplitOnRestElement<[number, string?, ...boolean[]], {preserveOptionalModifier: false}>` returns `[[number, string], boolean[], []]`
|
|
20
|
+
- And, with it disabled, the result is: `[[number, string | undefined], boolean[], []]`
|
|
21
|
+
|
|
22
|
+
@default true
|
|
23
|
+
*/
|
|
24
|
+
preserveOptionalModifier?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type DefaultSplitOnRestElementOptions = {
|
|
28
|
+
preserveOptionalModifier: true;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
Splits an array into three parts, where the first contains all elements before the rest element, the second is the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element itself, and the third contains all elements after the rest element.
|
|
33
|
+
|
|
34
|
+
Note: If any of the parts are missing, then they will be represented as empty arrays. For example, `SplitOnRestElement<[string, number]>` returns `[[string, number], [], []]`, where parts corresponding to the rest element and elements after it are empty.
|
|
35
|
+
|
|
36
|
+
By default, the optional modifier (`?`) is preserved.
|
|
37
|
+
See {@link SplitOnRestElementOptions `SplitOnRestElementOptions`}.
|
|
38
|
+
|
|
39
|
+
@example
|
|
40
|
+
```ts
|
|
41
|
+
import type {SplitOnRestElement} from 'type-fest';
|
|
42
|
+
|
|
43
|
+
type T1 = SplitOnRestElement<[number, ...string[], boolean]>;
|
|
44
|
+
//=> [[number], string[], [boolean]]
|
|
45
|
+
|
|
46
|
+
type T2 = SplitOnRestElement<readonly [...boolean[], string]>;
|
|
47
|
+
//=> readonly [[], boolean[], [string]]
|
|
48
|
+
|
|
49
|
+
type T3 = SplitOnRestElement<[number, string?]>;
|
|
50
|
+
//=> [[number, string?], [], []]
|
|
51
|
+
|
|
52
|
+
type T4 = SplitOnRestElement<[number, string?], {preserveOptionalModifier: false}>;
|
|
53
|
+
//=> [[number, string], [], []]
|
|
54
|
+
|
|
55
|
+
type T5 = SplitOnRestElement<readonly [string?, ...number[]], {preserveOptionalModifier: false}>;
|
|
56
|
+
//=> readonly [[string], number[], []]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
@see {@link ExtractRestElement}
|
|
60
|
+
@see {@link ExcludeRestElement}
|
|
61
|
+
@category Array
|
|
62
|
+
*/
|
|
63
|
+
export type SplitOnRestElement<
|
|
64
|
+
Array_ extends UnknownArray,
|
|
65
|
+
Options extends SplitOnRestElementOptions = {},
|
|
66
|
+
> =
|
|
67
|
+
Array_ extends unknown // For distributing `Array_`
|
|
68
|
+
? IfNotAnyOrNever<Array_, _SplitOnRestElement<
|
|
69
|
+
Array_,
|
|
70
|
+
ApplyDefaultOptions<SplitOnRestElementOptions, DefaultSplitOnRestElementOptions, Options>
|
|
71
|
+
>> extends infer Result extends UnknownArray
|
|
72
|
+
? If<IsArrayReadonly<Array_>, Readonly<Result>, Result>
|
|
73
|
+
: never // Should never happen
|
|
74
|
+
: never; // Should never happen
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
Deconstructs an array on its rest element and returns the split portions.
|
|
78
|
+
*/
|
|
79
|
+
export type _SplitOnRestElement<
|
|
80
|
+
Array_ extends UnknownArray,
|
|
81
|
+
Options extends Required<SplitOnRestElementOptions>,
|
|
82
|
+
HeadAcc extends UnknownArray = [],
|
|
83
|
+
TailAcc extends UnknownArray = [],
|
|
84
|
+
> =
|
|
85
|
+
keyof Array_ & `${number}` extends never
|
|
86
|
+
// Enters this branch, if `Array_` is empty (e.g., []),
|
|
87
|
+
// or `Array_` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`).
|
|
88
|
+
? Array_ extends readonly [...infer Rest, infer Last]
|
|
89
|
+
? _SplitOnRestElement<Rest, Options, HeadAcc, [Last, ...TailAcc]> // Accumulate elements that are present after the rest element.
|
|
90
|
+
: [HeadAcc, Array_ extends readonly [] ? [] : Array_, TailAcc] // Add the rest element between the accumulated elements.
|
|
91
|
+
: Array_ extends readonly [(infer First)?, ...infer Rest]
|
|
92
|
+
? _SplitOnRestElement<
|
|
93
|
+
Rest, Options,
|
|
94
|
+
[
|
|
95
|
+
...HeadAcc,
|
|
96
|
+
...IsOptionalKeyOf<Array_, '0'> extends true
|
|
97
|
+
? Options['preserveOptionalModifier'] extends false
|
|
98
|
+
? [If<IsExactOptionalPropertyTypesEnabled, First, First | undefined>] // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
|
|
99
|
+
: [First?]
|
|
100
|
+
: [First],
|
|
101
|
+
],
|
|
102
|
+
TailAcc
|
|
103
|
+
> // Accumulate elements that are present before the rest element.
|
|
104
|
+
: never; // Should never happen, since `[(infer First)?, ...infer Rest]` is a top-type for arrays.
|
|
105
|
+
|
|
106
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type {And} from './and.d.ts';
|
|
2
|
+
import type {ApplyDefaultOptions, Not} from './internal/index.d.ts';
|
|
3
|
+
import type {IsStringLiteral} from './is-literal.d.ts';
|
|
4
|
+
import type {Or} from './or.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Split options.
|
|
8
|
+
|
|
9
|
+
@see {@link Split}
|
|
10
|
+
*/
|
|
11
|
+
export type SplitOptions = {
|
|
12
|
+
/**
|
|
13
|
+
When enabled, instantiations with non-literal string types (e.g., `string`, `Uppercase<string>`, `on${string}`) simply return back `string[]` without performing any splitting, as the exact structure cannot be statically determined.
|
|
14
|
+
|
|
15
|
+
@default true
|
|
16
|
+
|
|
17
|
+
@example
|
|
18
|
+
```ts
|
|
19
|
+
import type {Split} from 'type-fest';
|
|
20
|
+
|
|
21
|
+
type Example1 = Split<`foo.${string}.bar`, '.', {strictLiteralChecks: false}>;
|
|
22
|
+
//=> ['foo', string, 'bar']
|
|
23
|
+
|
|
24
|
+
type Example2 = Split<`foo.${string}`, '.', {strictLiteralChecks: true}>;
|
|
25
|
+
//=> string[]
|
|
26
|
+
|
|
27
|
+
type Example3 = Split<'foobarbaz', `b${string}`, {strictLiteralChecks: false}>;
|
|
28
|
+
//=> ['foo', 'r', 'z']
|
|
29
|
+
|
|
30
|
+
type Example4 = Split<'foobarbaz', `b${string}`, {strictLiteralChecks: true}>;
|
|
31
|
+
//=> string[]
|
|
32
|
+
```
|
|
33
|
+
*/
|
|
34
|
+
strictLiteralChecks?: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type DefaultSplitOptions = {
|
|
38
|
+
strictLiteralChecks: true;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
Represents an array of strings split using a given character or character set.
|
|
43
|
+
|
|
44
|
+
Use-case: Defining the return type of a method like `String.prototype.split`.
|
|
45
|
+
|
|
46
|
+
@example
|
|
47
|
+
```
|
|
48
|
+
import type {Split} from 'type-fest';
|
|
49
|
+
|
|
50
|
+
declare function split<S extends string, D extends string>(string: S, separator: D): Split<S, D>;
|
|
51
|
+
|
|
52
|
+
type Item = 'foo' | 'bar' | 'baz' | 'waldo';
|
|
53
|
+
const items = 'foo,bar,baz,waldo';
|
|
54
|
+
const array: Item[] = split(items, ',');
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
@see {@link SplitOptions}
|
|
58
|
+
|
|
59
|
+
@category String
|
|
60
|
+
@category Template literal
|
|
61
|
+
*/
|
|
62
|
+
export type Split<
|
|
63
|
+
S extends string,
|
|
64
|
+
Delimiter extends string,
|
|
65
|
+
Options extends SplitOptions = {},
|
|
66
|
+
> =
|
|
67
|
+
SplitHelper<S, Delimiter, ApplyDefaultOptions<SplitOptions, DefaultSplitOptions, Options>>;
|
|
68
|
+
|
|
69
|
+
type SplitHelper<
|
|
70
|
+
S extends string,
|
|
71
|
+
Delimiter extends string,
|
|
72
|
+
Options extends Required<SplitOptions>,
|
|
73
|
+
Accumulator extends string[] = [],
|
|
74
|
+
> = S extends string // For distributing `S`
|
|
75
|
+
? Delimiter extends string // For distributing `Delimiter`
|
|
76
|
+
// If `strictLiteralChecks` is `false` OR `S` and `Delimiter` both are string literals, then perform the split
|
|
77
|
+
? Or<Not<Options['strictLiteralChecks']>, And<IsStringLiteral<S>, IsStringLiteral<Delimiter>>> extends true
|
|
78
|
+
? S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
79
|
+
? SplitHelper<Tail, Delimiter, Options, [...Accumulator, Head]>
|
|
80
|
+
: Delimiter extends ''
|
|
81
|
+
? S extends ''
|
|
82
|
+
? Accumulator
|
|
83
|
+
: [...Accumulator, S]
|
|
84
|
+
: [...Accumulator, S]
|
|
85
|
+
// Otherwise, return `string[]`
|
|
86
|
+
: string[]
|
|
87
|
+
: never // Should never happen
|
|
88
|
+
: never; // Should never happen
|
|
89
|
+
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type {RequiredKeysOf} from './required-keys-of.d.ts';
|
|
2
|
+
import type {Simplify} from './simplify.d.ts';
|
|
3
|
+
|
|
4
|
+
type SpreadObject<FirstType extends object, SecondType extends object> = {
|
|
5
|
+
[Key in keyof FirstType]: Key extends keyof SecondType
|
|
6
|
+
? FirstType[Key] | Required<SecondType>[Key]
|
|
7
|
+
: FirstType[Key];
|
|
8
|
+
} & Pick<
|
|
9
|
+
SecondType,
|
|
10
|
+
RequiredKeysOf<SecondType> | Exclude<keyof SecondType, keyof FirstType>
|
|
11
|
+
>;
|
|
12
|
+
|
|
13
|
+
type TupleOrArray = readonly [...unknown[]];
|
|
14
|
+
|
|
15
|
+
type SpreadTupleOrArray<
|
|
16
|
+
FirstType extends TupleOrArray,
|
|
17
|
+
SecondType extends TupleOrArray,
|
|
18
|
+
> = Array<FirstType[number] | SecondType[number]>;
|
|
19
|
+
|
|
20
|
+
type Spreadable = object | TupleOrArray;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
```
|
|
27
|
+
import type {Spread} from 'type-fest';
|
|
28
|
+
|
|
29
|
+
type Foo = {
|
|
30
|
+
a: number;
|
|
31
|
+
b?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type Bar = {
|
|
35
|
+
b?: number;
|
|
36
|
+
c: boolean;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const foo = {a: 1, b: '2'};
|
|
40
|
+
const bar = {c: false};
|
|
41
|
+
const fooBar = {...foo, ...bar};
|
|
42
|
+
|
|
43
|
+
type FooBar = Spread<Foo, Bar>;
|
|
44
|
+
// type FooBar = {
|
|
45
|
+
// a: number;
|
|
46
|
+
// b?: string | number | undefined;
|
|
47
|
+
// c: boolean;
|
|
48
|
+
// }
|
|
49
|
+
|
|
50
|
+
declare function baz(argument: FooBar): void;
|
|
51
|
+
|
|
52
|
+
baz(fooBar);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
@example
|
|
56
|
+
```
|
|
57
|
+
import type {Spread} from 'type-fest';
|
|
58
|
+
|
|
59
|
+
const foo = [1, 2, 3];
|
|
60
|
+
const bar = ['4', '5', '6'];
|
|
61
|
+
|
|
62
|
+
const fooBar = [...foo, ...bar];
|
|
63
|
+
type FooBar = Spread<typeof foo, typeof bar>;
|
|
64
|
+
// FooBar = (string | number)[]
|
|
65
|
+
|
|
66
|
+
declare function baz(argument: FooBar): void;
|
|
67
|
+
|
|
68
|
+
baz(fooBar);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
@category Object
|
|
72
|
+
*/
|
|
73
|
+
export type Spread<
|
|
74
|
+
FirstType extends Spreadable,
|
|
75
|
+
SecondType extends Spreadable,
|
|
76
|
+
> = FirstType extends TupleOrArray
|
|
77
|
+
? SecondType extends TupleOrArray
|
|
78
|
+
? SpreadTupleOrArray<FirstType, SecondType>
|
|
79
|
+
: Simplify<SpreadObject<FirstType, SecondType>>
|
|
80
|
+
: Simplify<SpreadObject<FirstType, SecondType>>;
|
|
81
|
+
|
|
82
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type {IsNumericLiteral} from './is-literal.d.ts';
|
|
2
|
+
import type {IsNegative} from './numeric.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Returns a new string which contains the specified number of copies of a given string, just like `String#repeat()`.
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
import type {StringRepeat} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
declare function stringRepeat<
|
|
12
|
+
Input extends string,
|
|
13
|
+
Count extends number,
|
|
14
|
+
>(input: Input, count: Count): StringRepeat<Input, Count>;
|
|
15
|
+
|
|
16
|
+
// The return type is the exact string literal, not just `string`.
|
|
17
|
+
|
|
18
|
+
stringRepeat('foo', 2);
|
|
19
|
+
//=> 'foofoo'
|
|
20
|
+
|
|
21
|
+
stringRepeat('=', 3);
|
|
22
|
+
//=> '==='
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
@category String
|
|
26
|
+
@category Template literal
|
|
27
|
+
*/
|
|
28
|
+
export type StringRepeat<
|
|
29
|
+
Input extends string,
|
|
30
|
+
Count extends number,
|
|
31
|
+
> = StringRepeatHelper<Input, Count>;
|
|
32
|
+
|
|
33
|
+
type StringRepeatHelper<
|
|
34
|
+
Input extends string,
|
|
35
|
+
Count extends number,
|
|
36
|
+
Counter extends never[] = [],
|
|
37
|
+
Accumulator extends string = '',
|
|
38
|
+
> =
|
|
39
|
+
IsNegative<Count> extends true
|
|
40
|
+
? never
|
|
41
|
+
: Input extends ''
|
|
42
|
+
? ''
|
|
43
|
+
: Count extends Counter['length']
|
|
44
|
+
? Accumulator
|
|
45
|
+
: IsNumericLiteral<Count> extends false
|
|
46
|
+
? string
|
|
47
|
+
: StringRepeatHelper<Input, Count, [...Counter, never], `${Accumulator}${Input}`>;
|
|
48
|
+
|
|
49
|
+
export {};
|