@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,80 @@
|
|
|
1
|
+
import type {If} from './if.d.ts';
|
|
2
|
+
import type {IfNotAnyOrNever} from './internal/type.d.ts';
|
|
3
|
+
import type {IsNegative} from './numeric.d.ts';
|
|
4
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Create a tuple type of the specified length with elements of the specified type.
|
|
8
|
+
|
|
9
|
+
@example
|
|
10
|
+
```
|
|
11
|
+
import type {TupleOf} from 'type-fest';
|
|
12
|
+
|
|
13
|
+
type RGB = TupleOf<3, number>;
|
|
14
|
+
//=> [number, number, number]
|
|
15
|
+
|
|
16
|
+
type Line = TupleOf<2, {x: number; y: number}>;
|
|
17
|
+
//=> [{x: number; y: number}, {x: number; y: number}]
|
|
18
|
+
|
|
19
|
+
type TicTacToeBoard = TupleOf<3, TupleOf<3, 'X' | 'O' | null>>;
|
|
20
|
+
//=> [['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null], ['X' | 'O' | null, 'X' | 'O' | null, 'X' | 'O' | null]]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
```
|
|
25
|
+
import type {TupleOf} from 'type-fest';
|
|
26
|
+
|
|
27
|
+
type Range<Start extends number, End extends number> = Exclude<keyof TupleOf<End>, keyof TupleOf<Start>>;
|
|
28
|
+
|
|
29
|
+
type ZeroToFour = Range<0, 5>;
|
|
30
|
+
//=> '0' | '1' | '2' | '3' | '4'
|
|
31
|
+
|
|
32
|
+
type ThreeToEight = Range<3, 9>;
|
|
33
|
+
//=> '5' | '3' | '4' | '6' | '7' | '8'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Note: If the specified length is the non-literal `number` type, the result will not be a tuple but a regular array.
|
|
37
|
+
|
|
38
|
+
@example
|
|
39
|
+
```
|
|
40
|
+
import type {TupleOf} from 'type-fest';
|
|
41
|
+
|
|
42
|
+
type StringArray = TupleOf<number, string>;
|
|
43
|
+
//=> string[]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Note: If the type for elements is not specified, it will default to `unknown`.
|
|
47
|
+
|
|
48
|
+
@example
|
|
49
|
+
```
|
|
50
|
+
import type {TupleOf} from 'type-fest';
|
|
51
|
+
|
|
52
|
+
type UnknownTriplet = TupleOf<3>;
|
|
53
|
+
//=> [unknown, unknown, unknown]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Note: If the specified length is negative, the result will be an empty tuple.
|
|
57
|
+
|
|
58
|
+
@example
|
|
59
|
+
```
|
|
60
|
+
import type {TupleOf} from 'type-fest';
|
|
61
|
+
|
|
62
|
+
type EmptyTuple = TupleOf<-3, string>;
|
|
63
|
+
//=> []
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Note: If you need a readonly tuple, simply wrap this type with `Readonly`, for example, to create `readonly [number, number, number]` use `Readonly<TupleOf<3, number>>`.
|
|
67
|
+
|
|
68
|
+
@category Array
|
|
69
|
+
*/
|
|
70
|
+
export type TupleOf<Length extends number, Fill = unknown> = IfNotAnyOrNever<Length,
|
|
71
|
+
_TupleOf<If<IsNegative<Length>, 0, Length>, Fill, []>,
|
|
72
|
+
Fill[], []>;
|
|
73
|
+
|
|
74
|
+
type _TupleOf<L extends number, Fill, Accumulator extends UnknownArray> = number extends L
|
|
75
|
+
? Fill[]
|
|
76
|
+
: L extends Accumulator['length']
|
|
77
|
+
? Accumulator
|
|
78
|
+
: _TupleOf<L, Fill, [...Accumulator, Fill]>;
|
|
79
|
+
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type {IsTuple} from './is-tuple.d.ts';
|
|
2
|
+
import type {UnknownArray} from './unknown-array.d.ts';
|
|
3
|
+
import type {IsAny} from './is-any.d.ts';
|
|
4
|
+
import type {If} from './if.d.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
Transforms a tuple into an object, mapping each tuple index to its corresponding type as a key-value pair.
|
|
8
|
+
|
|
9
|
+
Note: Tuple labels are [lost in the transformation process](https://stackoverflow.com/a/70398429/11719314). For example, `TupleToObject<[x: number, y: number]>` produces `{0: number; 1: number}`, and not `{x: number; y: number}`.
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```
|
|
13
|
+
import type {TupleToObject} from 'type-fest';
|
|
14
|
+
|
|
15
|
+
type Example1 = TupleToObject<[number, string, boolean]>;
|
|
16
|
+
//=> {0: number; 1: string; 2: boolean}
|
|
17
|
+
|
|
18
|
+
// Tuples with optional indices
|
|
19
|
+
type Example2 = TupleToObject<[number, string?, boolean?]>;
|
|
20
|
+
//=> {0: number; 1?: string; 2?: boolean}
|
|
21
|
+
|
|
22
|
+
// Readonly tuples
|
|
23
|
+
type Example3 = TupleToObject<readonly [number, string?]>;
|
|
24
|
+
//=> {readonly 0: number; readonly 1?: string}
|
|
25
|
+
|
|
26
|
+
// Non-tuple arrays get transformed into index signatures
|
|
27
|
+
type Example4 = TupleToObject<string[]>;
|
|
28
|
+
//=> {[x: number]: string}
|
|
29
|
+
|
|
30
|
+
// Tuples with rest elements
|
|
31
|
+
type Example5 = TupleToObject<[number, string, ...boolean[]]>;
|
|
32
|
+
//=> {[x: number]: string | number | boolean; 0: number; 1: string}
|
|
33
|
+
|
|
34
|
+
// Tuple labels are not preserved
|
|
35
|
+
type Example6 = TupleToObject<[x: number, y: number]>;
|
|
36
|
+
//=> {0: number; 1: number}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
@category Array
|
|
40
|
+
*/
|
|
41
|
+
export type TupleToObject<TArray extends UnknownArray> = If<IsAny<TArray>, any, {
|
|
42
|
+
[
|
|
43
|
+
Key in keyof TArray as Key & (`${number}` | (IsTuple<TArray> extends true ? never : number))
|
|
44
|
+
]: TArray[Key];
|
|
45
|
+
}>;
|
|
46
|
+
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Convert a tuple/array into a union type of its elements.
|
|
3
|
+
|
|
4
|
+
This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {TupleToUnion} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
const destinations = ['a', 'b', 'c'] as const;
|
|
11
|
+
|
|
12
|
+
type Destination = TupleToUnion<typeof destinations>;
|
|
13
|
+
//=> 'a' | 'b' | 'c'
|
|
14
|
+
|
|
15
|
+
function verifyDestination(destination: unknown): destination is Destination {
|
|
16
|
+
return destinations.includes(destination as any);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type RequestBody = {
|
|
20
|
+
deliverTo: Destination;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function verifyRequestBody(body: unknown): body is RequestBody {
|
|
24
|
+
const {deliverTo} = (body as any);
|
|
25
|
+
return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided.
|
|
30
|
+
|
|
31
|
+
@example
|
|
32
|
+
```
|
|
33
|
+
const destinations = ['a', 'b', 'c'] as const;
|
|
34
|
+
|
|
35
|
+
type Destination = typeof destinations[number];
|
|
36
|
+
//=> 'a' | 'b' | 'c'
|
|
37
|
+
|
|
38
|
+
const erroringType = new Set(['a', 'b', 'c']);
|
|
39
|
+
|
|
40
|
+
// @ts-expect-error
|
|
41
|
+
type ErroringType = typeof erroringType[number];
|
|
42
|
+
// Error: Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
|
|
43
|
+
|
|
44
|
+
const numberBool: {[n: number]: boolean} = {1: true};
|
|
45
|
+
|
|
46
|
+
type NumberBool = typeof numberBool[number];
|
|
47
|
+
//=> boolean
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
@category Array
|
|
51
|
+
*/
|
|
52
|
+
export type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;
|
|
53
|
+
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`.
|
|
3
|
+
|
|
4
|
+
@category Array
|
|
5
|
+
*/
|
|
6
|
+
export type TypedArray =
|
|
7
|
+
| Int8Array
|
|
8
|
+
| Uint8Array
|
|
9
|
+
| Uint8ClampedArray
|
|
10
|
+
| Int16Array
|
|
11
|
+
| Uint16Array
|
|
12
|
+
| Int32Array
|
|
13
|
+
| Uint32Array
|
|
14
|
+
| Float32Array
|
|
15
|
+
| Float64Array
|
|
16
|
+
| BigInt64Array
|
|
17
|
+
| BigUint64Array;
|
|
18
|
+
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type {BuiltIns} from './internal/index.d.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Create a deep version of another type where all optional keys are set to also accept `undefined`.
|
|
5
|
+
|
|
6
|
+
Note: This is only needed when the [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes) TSConfig setting is enabled.
|
|
7
|
+
|
|
8
|
+
Use-cases:
|
|
9
|
+
- When `exactOptionalPropertyTypes` is enabled, an object like `{a: undefined}` is not assignable to the type `{a?: number}`. You can use `UndefinedOnPartialDeep<{a?: number}>` to make it assignable.
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```
|
|
13
|
+
import type {UndefinedOnPartialDeep} from 'type-fest';
|
|
14
|
+
|
|
15
|
+
type Settings = {
|
|
16
|
+
optionA: string;
|
|
17
|
+
optionB?: number;
|
|
18
|
+
subOption: {
|
|
19
|
+
subOptionA: boolean;
|
|
20
|
+
subOptionB?: boolean;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const testSettingsA: Settings = {
|
|
25
|
+
optionA: 'foo',
|
|
26
|
+
optionB: undefined, // TypeScript error if `exactOptionalPropertyTypes` is true.
|
|
27
|
+
// @ts-expect-error
|
|
28
|
+
subOption: {
|
|
29
|
+
subOptionA: true,
|
|
30
|
+
subOptionB: undefined, // TypeScript error if `exactOptionalPropertyTypes` is true
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const testSettingsB: UndefinedOnPartialDeep<Settings> = {
|
|
35
|
+
optionA: 'foo',
|
|
36
|
+
optionB: undefined, // `optionB` can be set to `undefined` now.
|
|
37
|
+
subOption: {
|
|
38
|
+
subOptionA: true,
|
|
39
|
+
subOptionB: undefined, // `subOptionB` can be set to `undefined` now.
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
*/
|
|
44
|
+
export type UndefinedOnPartialDeep<T> =
|
|
45
|
+
// Handle built-in type and function
|
|
46
|
+
T extends BuiltIns | Function
|
|
47
|
+
? T
|
|
48
|
+
// Handle tuple and array
|
|
49
|
+
: T extends readonly unknown[]
|
|
50
|
+
? UndefinedOnPartialList<T>
|
|
51
|
+
// Handle map and readonly map
|
|
52
|
+
: T extends Map<infer K, infer V>
|
|
53
|
+
? Map<K, UndefinedOnPartialDeep<V>>
|
|
54
|
+
: T extends ReadonlyMap<infer K, infer V>
|
|
55
|
+
? ReadonlyMap<K, UndefinedOnPartialDeep<V>>
|
|
56
|
+
// Handle set and readonly set
|
|
57
|
+
: T extends Set<infer K>
|
|
58
|
+
? Set<UndefinedOnPartialDeep<K>>
|
|
59
|
+
: T extends ReadonlySet<infer K>
|
|
60
|
+
? ReadonlySet<UndefinedOnPartialDeep<K>>
|
|
61
|
+
// Handle object
|
|
62
|
+
: T extends Record<any, any>
|
|
63
|
+
? {
|
|
64
|
+
[KeyType in keyof T]: undefined extends T[KeyType]
|
|
65
|
+
? UndefinedOnPartialDeep<T[KeyType]> | undefined
|
|
66
|
+
: UndefinedOnPartialDeep<T[KeyType]>
|
|
67
|
+
}
|
|
68
|
+
: T; // If T is not builtins / function / array / map / set / object, return T
|
|
69
|
+
|
|
70
|
+
// Handle tuples and arrays
|
|
71
|
+
type UndefinedOnPartialList<T extends readonly unknown[]> = T extends []
|
|
72
|
+
? []
|
|
73
|
+
: T extends [infer F, ...infer R]
|
|
74
|
+
? [UndefinedOnPartialDeep<F>, ...UndefinedOnPartialDeep<R>]
|
|
75
|
+
: T extends readonly [infer F, ...infer R]
|
|
76
|
+
? readonly [UndefinedOnPartialDeep<F>, ...UndefinedOnPartialDeep<R>]
|
|
77
|
+
: T extends Array<infer F>
|
|
78
|
+
? Array<UndefinedOnPartialDeep<F>>
|
|
79
|
+
: T extends ReadonlyArray<infer F>
|
|
80
|
+
? ReadonlyArray<UndefinedOnPartialDeep<F>>
|
|
81
|
+
: never;
|
|
82
|
+
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
3
|
+
|
|
4
|
+
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnionToIntersection} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
11
|
+
|
|
12
|
+
type Intersection = UnionToIntersection<Union>;
|
|
13
|
+
//=> {the(): void} & {great(arg: string): void} & {escape: boolean}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
@category Type
|
|
17
|
+
*/
|
|
18
|
+
export type UnionToIntersection<Union> = (
|
|
19
|
+
// `extends unknown` is always going to be the case and is used to convert the
|
|
20
|
+
// `Union` into a [distributive conditional
|
|
21
|
+
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
22
|
+
Union extends unknown
|
|
23
|
+
// The union type is used as the only argument to a function since the union
|
|
24
|
+
// of function arguments is an intersection.
|
|
25
|
+
? (distributedUnion: Union) => void
|
|
26
|
+
// This won't happen.
|
|
27
|
+
: never
|
|
28
|
+
// Infer the `Intersection` type since TypeScript represents the positional
|
|
29
|
+
// arguments of unions of functions as an intersection of the union.
|
|
30
|
+
) extends ((mergedIntersection: infer Intersection) => void)
|
|
31
|
+
// The `& Union` is to ensure result of `UnionToIntersection<A | B>` is always assignable to `A | B`
|
|
32
|
+
? Intersection & Union
|
|
33
|
+
: never;
|
|
34
|
+
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type {IsNever} from './is-never.d.ts';
|
|
2
|
+
import type {UnionToIntersection} from './union-to-intersection.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Returns the last element of a union type.
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
type Last = LastOfUnion<1 | 2 | 3>;
|
|
10
|
+
//=> 3
|
|
11
|
+
```
|
|
12
|
+
*/
|
|
13
|
+
type LastOfUnion<T> =
|
|
14
|
+
UnionToIntersection<T extends any ? () => T : never> extends () => (infer R)
|
|
15
|
+
? R
|
|
16
|
+
: never;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
Convert a union type into an unordered tuple type of its elements.
|
|
20
|
+
|
|
21
|
+
"Unordered" means the elements of the tuple are not guaranteed to be in the same order as in the union type. The arrangement can appear random and may change at any time.
|
|
22
|
+
|
|
23
|
+
This can be useful when you have objects with a finite set of keys and want a type defining only the allowed keys, but do not want to repeat yourself.
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
```
|
|
27
|
+
import type {UnionToTuple} from 'type-fest';
|
|
28
|
+
|
|
29
|
+
type Numbers = 1 | 2 | 3;
|
|
30
|
+
type NumbersTuple = UnionToTuple<Numbers>;
|
|
31
|
+
//=> [1, 2, 3]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
@example
|
|
35
|
+
```
|
|
36
|
+
import type {UnionToTuple} from 'type-fest';
|
|
37
|
+
|
|
38
|
+
const pets = {
|
|
39
|
+
dog: '🐶',
|
|
40
|
+
cat: '🐱',
|
|
41
|
+
snake: '🐍',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type Pet = keyof typeof pets;
|
|
45
|
+
//=> 'dog' | 'cat' | 'snake'
|
|
46
|
+
|
|
47
|
+
const petList = Object.keys(pets) as UnionToTuple<Pet>;
|
|
48
|
+
//=> ['dog', 'cat', 'snake']
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
@category Array
|
|
52
|
+
*/
|
|
53
|
+
export type UnionToTuple<T, L = LastOfUnion<T>> =
|
|
54
|
+
IsNever<T> extends false
|
|
55
|
+
? [...UnionToTuple<Exclude<T, L>>, L]
|
|
56
|
+
: [];
|
|
57
|
+
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Represents an array with `unknown` value.
|
|
3
|
+
|
|
4
|
+
Use case: You want a type that all arrays can be assigned to, but you don't care about the value.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnknownArray} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type IsArray<T> = T extends UnknownArray ? true : false;
|
|
11
|
+
|
|
12
|
+
type A = IsArray<['foo']>;
|
|
13
|
+
//=> true
|
|
14
|
+
|
|
15
|
+
type B = IsArray<readonly number[]>;
|
|
16
|
+
//=> true
|
|
17
|
+
|
|
18
|
+
type C = IsArray<string>;
|
|
19
|
+
//=> false
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
@category Type
|
|
23
|
+
@category Array
|
|
24
|
+
*/
|
|
25
|
+
export type UnknownArray = readonly unknown[];
|
|
26
|
+
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Represents a map with `unknown` key and value.
|
|
3
|
+
|
|
4
|
+
Use case: You want a type that all maps can be assigned to, but you don't care about the value.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnknownMap} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type IsMap<T> = T extends UnknownMap ? true : false;
|
|
11
|
+
|
|
12
|
+
type A = IsMap<Map<string, number>>;
|
|
13
|
+
//=> true
|
|
14
|
+
|
|
15
|
+
type B = IsMap<ReadonlyMap<number, string>>;
|
|
16
|
+
//=> true
|
|
17
|
+
|
|
18
|
+
type C = IsMap<string>;
|
|
19
|
+
//=> false
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
@category Type
|
|
23
|
+
*/
|
|
24
|
+
export type UnknownMap = ReadonlyMap<unknown, unknown>;
|
|
25
|
+
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Represents an object with `unknown` value. You probably want this instead of `{}`.
|
|
3
|
+
|
|
4
|
+
Use case: You have an object whose keys and values are unknown to you.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnknownRecord} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
function toJson(object: UnknownRecord) {
|
|
11
|
+
return JSON.stringify(object);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
toJson({hello: 'world'}); // Ok
|
|
15
|
+
|
|
16
|
+
function isObject(value: unknown): value is UnknownRecord {
|
|
17
|
+
return typeof value === 'object' && value !== null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const value: unknown = {hello: 'world'};
|
|
21
|
+
|
|
22
|
+
if (isObject(value)) {
|
|
23
|
+
const v = value;
|
|
24
|
+
//=> UnknownRecord
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
@category Type
|
|
29
|
+
@category Object
|
|
30
|
+
*/
|
|
31
|
+
export type UnknownRecord = Record<PropertyKey, unknown>;
|
|
32
|
+
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Represents a set with `unknown` value.
|
|
3
|
+
|
|
4
|
+
Use case: You want a type that all sets can be assigned to, but you don't care about the value.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnknownSet} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type IsSet<T> = T extends UnknownSet ? true : false;
|
|
11
|
+
|
|
12
|
+
type A = IsSet<Set<string>>;
|
|
13
|
+
//=> true
|
|
14
|
+
|
|
15
|
+
type B = IsSet<ReadonlySet<number>>;
|
|
16
|
+
//=> true
|
|
17
|
+
|
|
18
|
+
type C = IsSet<string>;
|
|
19
|
+
//=> false
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
@category Type
|
|
23
|
+
*/
|
|
24
|
+
export type UnknownSet = ReadonlySet<unknown>;
|
|
25
|
+
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Revert the `Partial` modifier on an object type.
|
|
3
|
+
|
|
4
|
+
Use-case: Infer the underlying type `T` when only `Partial<T>` is available or the original type may not be directly accessible.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {UnwrapPartial} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type Config = Partial<{
|
|
11
|
+
port: number;
|
|
12
|
+
host: string;
|
|
13
|
+
secure?: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
type InitializedConfig = UnwrapPartial<Config>;
|
|
17
|
+
//=> {port: number; host: string; secure?: boolean}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Note: If the provided type isn’t of `Partial<T>`, `UnwrapPartial` has no effect on the original type.
|
|
21
|
+
|
|
22
|
+
@category Object
|
|
23
|
+
*/
|
|
24
|
+
export type UnwrapPartial<PartialObjectType> =
|
|
25
|
+
PartialObjectType extends Partial<infer ObjectType>
|
|
26
|
+
? (
|
|
27
|
+
Partial<ObjectType> extends PartialObjectType
|
|
28
|
+
? ObjectType
|
|
29
|
+
: PartialObjectType
|
|
30
|
+
)
|
|
31
|
+
: PartialObjectType;
|
|
32
|
+
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Create a union of the given object's values, and optionally specify which keys to get the values from.
|
|
3
|
+
|
|
4
|
+
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31438) if you want to have this type as a built-in in TypeScript.
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
```
|
|
8
|
+
import type {ValueOf} from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type A = ValueOf<{id: number; name: string; active: boolean}>;
|
|
11
|
+
//=> string | number | boolean
|
|
12
|
+
|
|
13
|
+
type B = ValueOf<{id: number; name: string; active: boolean}, 'name'>;
|
|
14
|
+
//=> string
|
|
15
|
+
|
|
16
|
+
type C = ValueOf<{id: number; name: string; active: boolean}, 'id' | 'name'>;
|
|
17
|
+
//=> string | number
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
@category Object
|
|
21
|
+
*/
|
|
22
|
+
export type ValueOf<ObjectType, ValueType extends keyof ObjectType = keyof ObjectType> = ObjectType[ValueType];
|
|
23
|
+
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ApplyDefaultOptions,
|
|
3
|
+
IsNumeric,
|
|
4
|
+
WordSeparators,
|
|
5
|
+
} from './internal/index.d.ts';
|
|
6
|
+
import type {IsLowercase} from './is-lowercase.d.ts';
|
|
7
|
+
import type {IsUppercase} from './is-uppercase.d.ts';
|
|
8
|
+
|
|
9
|
+
type SkipEmptyWord<Word extends string> = Word extends '' ? [] : [Word];
|
|
10
|
+
|
|
11
|
+
type RemoveLastCharacter<
|
|
12
|
+
Sentence extends string,
|
|
13
|
+
Character extends string,
|
|
14
|
+
> = Sentence extends `${infer LeftSide}${Character}`
|
|
15
|
+
? SkipEmptyWord<LeftSide>
|
|
16
|
+
: never;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
Words options.
|
|
20
|
+
|
|
21
|
+
@see {@link Words}
|
|
22
|
+
*/
|
|
23
|
+
export type WordsOptions = {
|
|
24
|
+
/**
|
|
25
|
+
Split on numeric sequence.
|
|
26
|
+
|
|
27
|
+
@default true
|
|
28
|
+
|
|
29
|
+
@example
|
|
30
|
+
```
|
|
31
|
+
import type {Words} from 'type-fest';
|
|
32
|
+
|
|
33
|
+
type Example1 = Words<'p2pNetwork', {splitOnNumbers: true}>;
|
|
34
|
+
//=> ['p', '2', 'p', 'Network']
|
|
35
|
+
|
|
36
|
+
type Example2 = Words<'p2pNetwork', {splitOnNumbers: false}>;
|
|
37
|
+
//=> ['p2p', 'Network']
|
|
38
|
+
```
|
|
39
|
+
*/
|
|
40
|
+
splitOnNumbers?: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type _DefaultWordsOptions = {
|
|
44
|
+
splitOnNumbers: true;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
Split a string (almost) like Lodash's `_.words()` function.
|
|
49
|
+
|
|
50
|
+
- Split on each word that begins with a capital letter.
|
|
51
|
+
- Split on each {@link WordSeparators}.
|
|
52
|
+
- Split on numeric sequence.
|
|
53
|
+
|
|
54
|
+
@example
|
|
55
|
+
```
|
|
56
|
+
import type {Words} from 'type-fest';
|
|
57
|
+
|
|
58
|
+
type Words0 = Words<'helloWorld'>;
|
|
59
|
+
//=> ['hello', 'World']
|
|
60
|
+
|
|
61
|
+
type Words1 = Words<'helloWORLD'>;
|
|
62
|
+
//=> ['hello', 'WORLD']
|
|
63
|
+
|
|
64
|
+
type Words2 = Words<'hello-world'>;
|
|
65
|
+
//=> ['hello', 'world']
|
|
66
|
+
|
|
67
|
+
type Words3 = Words<'--hello the_world'>;
|
|
68
|
+
//=> ['hello', 'the', 'world']
|
|
69
|
+
|
|
70
|
+
type Words4 = Words<'lifeIs42'>;
|
|
71
|
+
//=> ['life', 'Is', '42']
|
|
72
|
+
|
|
73
|
+
type Words5 = Words<'p2pNetwork', {splitOnNumbers: false}>;
|
|
74
|
+
//=> ['p2p', 'Network']
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
@category Change case
|
|
78
|
+
@category Template literal
|
|
79
|
+
*/
|
|
80
|
+
export type Words<Sentence extends string, Options extends WordsOptions = {}> =
|
|
81
|
+
WordsImplementation<Sentence, ApplyDefaultOptions<WordsOptions, _DefaultWordsOptions, Options>>;
|
|
82
|
+
|
|
83
|
+
type WordsImplementation<
|
|
84
|
+
Sentence extends string,
|
|
85
|
+
Options extends Required<WordsOptions>,
|
|
86
|
+
LastCharacter extends string = '',
|
|
87
|
+
CurrentWord extends string = '',
|
|
88
|
+
> = Sentence extends `${infer FirstCharacter}${infer RemainingCharacters}`
|
|
89
|
+
? FirstCharacter extends WordSeparators
|
|
90
|
+
// Skip word separator
|
|
91
|
+
? [...SkipEmptyWord<CurrentWord>, ...WordsImplementation<RemainingCharacters, Options>]
|
|
92
|
+
: LastCharacter extends ''
|
|
93
|
+
// Fist char of word
|
|
94
|
+
? WordsImplementation<RemainingCharacters, Options, FirstCharacter, FirstCharacter>
|
|
95
|
+
// Case change: non-numeric to numeric
|
|
96
|
+
: [false, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
|
|
97
|
+
? Options['splitOnNumbers'] extends true
|
|
98
|
+
// Split on number: push word
|
|
99
|
+
? [...SkipEmptyWord<CurrentWord>, ...WordsImplementation<RemainingCharacters, Options, FirstCharacter, FirstCharacter>]
|
|
100
|
+
// No split on number: concat word
|
|
101
|
+
: WordsImplementation<RemainingCharacters, Options, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
|
|
102
|
+
// Case change: numeric to non-numeric
|
|
103
|
+
: [true, false] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
|
|
104
|
+
? Options['splitOnNumbers'] extends true
|
|
105
|
+
// Split on number: push word
|
|
106
|
+
? [...SkipEmptyWord<CurrentWord>, ...WordsImplementation<RemainingCharacters, Options, FirstCharacter, FirstCharacter>]
|
|
107
|
+
// No split on number: concat word
|
|
108
|
+
: WordsImplementation<RemainingCharacters, Options, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
|
|
109
|
+
// No case change: concat word
|
|
110
|
+
: [true, true] extends [IsNumeric<LastCharacter>, IsNumeric<FirstCharacter>]
|
|
111
|
+
? WordsImplementation<RemainingCharacters, Options, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
|
|
112
|
+
// Case change: lower to upper, push word
|
|
113
|
+
: [true, true] extends [IsLowercase<LastCharacter>, IsUppercase<FirstCharacter>]
|
|
114
|
+
? [...SkipEmptyWord<CurrentWord>, ...WordsImplementation<RemainingCharacters, Options, FirstCharacter, FirstCharacter>]
|
|
115
|
+
// Case change: upper to lower, brings back the last character, push word
|
|
116
|
+
: [true, true] extends [IsUppercase<LastCharacter>, IsLowercase<FirstCharacter>]
|
|
117
|
+
? [...RemoveLastCharacter<CurrentWord, LastCharacter>, ...WordsImplementation<RemainingCharacters, Options, FirstCharacter, `${LastCharacter}${FirstCharacter}`>]
|
|
118
|
+
// No case change: concat word
|
|
119
|
+
: WordsImplementation<RemainingCharacters, Options, FirstCharacter, `${CurrentWord}${FirstCharacter}`>
|
|
120
|
+
: [...SkipEmptyWord<CurrentWord>];
|
|
121
|
+
|
|
122
|
+
export {};
|