type-fest 5.4.4 → 5.6.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/index.d.ts +10 -0
- package/package.json +6 -4
- package/readme.md +83 -58
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +5 -6
- package/source/all-union-fields.d.ts +18 -18
- package/source/and-all.d.ts +76 -0
- package/source/and.d.ts +4 -3
- package/source/array-length.d.ts +36 -0
- package/source/array-splice.d.ts +26 -26
- package/source/camel-case.d.ts +38 -5
- package/source/camel-cased-properties-deep.d.ts +11 -4
- package/source/camel-cased-properties.d.ts +5 -1
- package/source/conditional-pick-deep.d.ts +5 -3
- package/source/conditional-pick.d.ts +6 -4
- package/source/delimiter-case.d.ts +1 -0
- package/source/delimiter-cased-properties-deep.d.ts +8 -1
- package/source/delimiter-cased-properties.d.ts +5 -1
- package/source/empty-object.d.ts +1 -1
- package/source/entries.d.ts +1 -1
- package/source/entry.d.ts +1 -1
- package/source/exclude-exactly.d.ts +57 -0
- package/source/get.d.ts +1 -1
- package/source/greater-than-or-equal.d.ts +34 -1
- package/source/greater-than.d.ts +37 -3
- package/source/has-optional-keys.d.ts +1 -1
- package/source/has-readonly-keys.d.ts +1 -1
- package/source/has-required-keys.d.ts +1 -1
- package/source/has-writable-keys.d.ts +1 -1
- package/source/int-closed-range.d.ts +1 -3
- package/source/int-range.d.ts +3 -5
- package/source/internal/array.d.ts +7 -14
- package/source/internal/keys.d.ts +9 -9
- package/source/internal/numeric.d.ts +13 -23
- package/source/internal/tuple.d.ts +3 -3
- package/source/internal/type.d.ts +1 -0
- package/source/is-equal.d.ts +0 -1
- package/source/is-integer.d.ts +8 -8
- package/source/is-literal.d.ts +5 -5
- package/source/is-union.d.ts +12 -12
- package/source/iterable-element.d.ts +5 -5
- package/source/jsonify.d.ts +4 -4
- package/source/kebab-case.d.ts +1 -0
- package/source/kebab-cased-properties-deep.d.ts +7 -0
- package/source/kebab-cased-properties.d.ts +5 -1
- package/source/keys-of-union.d.ts +2 -2
- package/source/less-than-or-equal.d.ts +40 -4
- package/source/less-than.d.ts +35 -3
- package/source/literal-to-primitive.d.ts +1 -1
- package/source/literal-union.d.ts +1 -1
- package/source/merge-exclusive.d.ts +3 -3
- package/source/merge.d.ts +25 -0
- package/source/multidimensional-array.d.ts +1 -1
- package/source/multidimensional-readonly-array.d.ts +1 -1
- package/source/non-nullable-deep.d.ts +102 -0
- package/source/numeric.d.ts +3 -3
- package/source/omit-deep.d.ts +22 -23
- package/source/optional.d.ts +31 -0
- package/source/or-all.d.ts +73 -0
- package/source/or.d.ts +4 -11
- package/source/package-json.d.ts +7 -7
- package/source/partial-deep.d.ts +3 -1
- package/source/pascal-case.d.ts +1 -0
- package/source/pascal-cased-properties-deep.d.ts +7 -0
- package/source/pascal-cased-properties.d.ts +5 -1
- package/source/pick-deep.d.ts +8 -21
- package/source/readonly-deep.d.ts +5 -3
- package/source/remove-prefix.d.ts +15 -15
- package/source/replace.d.ts +2 -2
- package/source/require-all-or-none.d.ts +1 -1
- package/source/require-at-least-one.d.ts +5 -7
- package/source/require-exactly-one.d.ts +3 -3
- package/source/require-one-or-none.d.ts +1 -1
- package/source/required-deep.d.ts +3 -1
- package/source/screaming-snake-case.d.ts +1 -0
- package/source/set-non-nullable-deep.d.ts +6 -3
- package/source/set-non-nullable.d.ts +4 -11
- package/source/set-optional.d.ts +6 -10
- package/source/set-parameter-type.d.ts +2 -2
- package/source/set-readonly.d.ts +4 -8
- package/source/set-required-deep.d.ts +1 -1
- package/source/set-required.d.ts +4 -8
- package/source/shared-union-fields-deep.d.ts +1 -1
- package/source/shared-union-fields.d.ts +9 -9
- package/source/snake-case.d.ts +1 -0
- package/source/snake-cased-properties-deep.d.ts +7 -0
- package/source/snake-cased-properties.d.ts +5 -1
- package/source/some-extend.d.ts +113 -0
- package/source/spread.d.ts +1 -5
- package/source/subtract.d.ts +4 -3
- package/source/sum.d.ts +5 -4
- package/source/tagged.d.ts +5 -7
- package/source/tsconfig-json.d.ts +39 -7
- package/source/union-length.d.ts +27 -0
- package/source/union-member.d.ts +65 -0
- package/source/union-to-intersection.d.ts +1 -1
- package/source/union-to-tuple.d.ts +10 -19
- package/source/words.d.ts +30 -4
- package/source/writable.d.ts +15 -19
- package/source/xor.d.ts +1 -1
|
@@ -4,13 +4,6 @@ import type {OptionalKeysOf} from '../optional-keys-of.d.ts';
|
|
|
4
4
|
import type {UnknownArray} from '../unknown-array.d.ts';
|
|
5
5
|
import type {IsExactOptionalPropertyTypesEnabled, IfNotAnyOrNever} from './type.d.ts';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
Infer the length of the given array `<T>`.
|
|
9
|
-
|
|
10
|
-
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
11
|
-
*/
|
|
12
|
-
type ArrayLength<T extends readonly unknown[]> = T extends {readonly length: infer L} ? L : never;
|
|
13
|
-
|
|
14
7
|
/**
|
|
15
8
|
Matches any unknown array or tuple.
|
|
16
9
|
*/
|
|
@@ -36,8 +29,8 @@ type B = StaticPartOfArray<A>;
|
|
|
36
29
|
*/
|
|
37
30
|
export type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
|
|
38
31
|
T extends unknown
|
|
39
|
-
? number extends T['length']
|
|
40
|
-
T extends readonly [infer U, ...infer V]
|
|
32
|
+
? number extends T['length']
|
|
33
|
+
? T extends readonly [infer U, ...infer V]
|
|
41
34
|
? StaticPartOfArray<V, [...Result, U]>
|
|
42
35
|
: Result
|
|
43
36
|
: T
|
|
@@ -76,11 +69,11 @@ type NormalResult = SetArrayAccess<ReadonlyStringArray, false>;
|
|
|
76
69
|
```
|
|
77
70
|
*/
|
|
78
71
|
export type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
|
|
79
|
-
T extends readonly [...infer U]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
T extends readonly [...infer U]
|
|
73
|
+
? IsReadonly extends true
|
|
74
|
+
? readonly [...U]
|
|
75
|
+
: [...U]
|
|
76
|
+
: T;
|
|
84
77
|
|
|
85
78
|
/**
|
|
86
79
|
Returns whether the given array `T` is readonly.
|
|
@@ -87,14 +87,14 @@ type Key4 = ExactKey<Object, 1>;
|
|
|
87
87
|
@category Object
|
|
88
88
|
*/
|
|
89
89
|
export type ExactKey<T extends object, Key extends PropertyKey> =
|
|
90
|
-
Key extends keyof T
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
90
|
+
Key extends keyof T
|
|
91
|
+
? Key
|
|
92
|
+
: ToString<Key> extends keyof T
|
|
93
|
+
? ToString<Key>
|
|
94
|
+
: Key extends `${infer NumberKey extends number}`
|
|
95
|
+
? NumberKey extends keyof T
|
|
96
|
+
? NumberKey
|
|
97
|
+
: never
|
|
98
|
+
: never;
|
|
99
99
|
|
|
100
100
|
export {};
|
|
@@ -1,26 +1,8 @@
|
|
|
1
1
|
import type {IsNever} from '../is-never.d.ts';
|
|
2
2
|
import type {Finite, NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
|
|
3
3
|
import type {UnknownArray} from '../unknown-array.d.ts';
|
|
4
|
-
import type {StringToNumber} from './string.d.ts';
|
|
5
4
|
import type {IfNotAnyOrNever, IsAnyOrNever} from './type.d.ts';
|
|
6
5
|
|
|
7
|
-
/**
|
|
8
|
-
Returns the absolute value of a given value.
|
|
9
|
-
|
|
10
|
-
@example
|
|
11
|
-
```
|
|
12
|
-
type A = NumberAbsolute<-1>;
|
|
13
|
-
//=> 1
|
|
14
|
-
|
|
15
|
-
type B = NumberAbsolute<1>;
|
|
16
|
-
//=> 1
|
|
17
|
-
|
|
18
|
-
type C = NumberAbsolute<NegativeInfinity>;
|
|
19
|
-
//=> PositiveInfinity
|
|
20
|
-
```
|
|
21
|
-
*/
|
|
22
|
-
export type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
|
|
23
|
-
|
|
24
6
|
/**
|
|
25
7
|
Check whether the given type is a number or a number string.
|
|
26
8
|
|
|
@@ -142,10 +124,18 @@ type D = ReverseSign<PositiveInfinity>;
|
|
|
142
124
|
*/
|
|
143
125
|
export type ReverseSign<N extends number> =
|
|
144
126
|
// Handle edge cases
|
|
145
|
-
N extends 0
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
127
|
+
N extends 0
|
|
128
|
+
? 0
|
|
129
|
+
: N extends PositiveInfinity
|
|
130
|
+
? NegativeInfinity
|
|
131
|
+
: N extends NegativeInfinity
|
|
132
|
+
? PositiveInfinity
|
|
133
|
+
// Handle negative numbers
|
|
134
|
+
: `${N}` extends `-${infer P extends number}`
|
|
135
|
+
? P
|
|
136
|
+
// Handle positive numbers
|
|
137
|
+
: `-${N}` extends `${infer R extends number}`
|
|
138
|
+
? R
|
|
139
|
+
: never;
|
|
150
140
|
|
|
151
141
|
export {};
|
|
@@ -23,7 +23,7 @@ type Union = TupleLength<[] | [1, 2, 3] | number[]>;
|
|
|
23
23
|
*/
|
|
24
24
|
export type TupleLength<T extends UnknownArray> =
|
|
25
25
|
// `extends unknown` is used to convert `T` (if `T` is a union type) to
|
|
26
|
-
// a [distributive
|
|
26
|
+
// a [distributive conditional type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types))
|
|
27
27
|
T extends unknown
|
|
28
28
|
? number extends T['length']
|
|
29
29
|
? never // Return never if the given type is an non-flexed-length array like `Array<string>`
|
|
@@ -46,8 +46,8 @@ type B = TupleMax<[1, 2, 5, 3, 99, -1]>;
|
|
|
46
46
|
```
|
|
47
47
|
*/
|
|
48
48
|
export type TupleMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
|
|
49
|
-
? never
|
|
50
|
-
A extends [infer F extends number, ...infer R extends number[]]
|
|
49
|
+
? never
|
|
50
|
+
: A extends [infer F extends number, ...infer R extends number[]]
|
|
51
51
|
? GreaterThan<F, Result> extends true
|
|
52
52
|
? TupleMax<R, F>
|
|
53
53
|
: TupleMax<R, Result>
|
|
@@ -3,6 +3,7 @@ import type {IsAny} from '../is-any.d.ts';
|
|
|
3
3
|
import type {IsNever} from '../is-never.d.ts';
|
|
4
4
|
import type {Primitive} from '../primitive.d.ts';
|
|
5
5
|
import type {UnknownArray} from '../unknown-array.d.ts';
|
|
6
|
+
import type {UnionToIntersection} from '../union-to-intersection.d.ts';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
Matches any primitive, `void`, `Date`, or `RegExp` value.
|
package/source/is-equal.d.ts
CHANGED
package/source/is-integer.d.ts
CHANGED
|
@@ -47,14 +47,14 @@ type J = IsInteger<1e-7>;
|
|
|
47
47
|
@category Numeric
|
|
48
48
|
*/
|
|
49
49
|
export type IsInteger<T> =
|
|
50
|
-
T extends bigint
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
? false
|
|
55
|
-
: T extends PositiveInfinity | NegativeInfinity
|
|
50
|
+
T extends bigint
|
|
51
|
+
? true
|
|
52
|
+
: T extends number
|
|
53
|
+
? number extends T
|
|
56
54
|
? false
|
|
57
|
-
:
|
|
58
|
-
|
|
55
|
+
: T extends PositiveInfinity | NegativeInfinity
|
|
56
|
+
? false
|
|
57
|
+
: Not<IsFloat<T>>
|
|
58
|
+
: false;
|
|
59
59
|
|
|
60
60
|
export {};
|
package/source/is-literal.d.ts
CHANGED
|
@@ -121,11 +121,11 @@ export type IsStringLiteral<S> = IfNotAnyOrNever<S,
|
|
|
121
121
|
export type _IsStringLiteral<S> =
|
|
122
122
|
// If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
|
|
123
123
|
// and since `{}` extends index signatures, the result becomes `false`.
|
|
124
|
-
S extends string
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
S extends string
|
|
125
|
+
? {} extends Record<S, never>
|
|
126
|
+
? false
|
|
127
|
+
: true
|
|
128
|
+
: false;
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
131
|
Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
package/source/is-union.d.ts
CHANGED
|
@@ -21,20 +21,20 @@ export type IsUnion<T> = InternalIsUnion<T>;
|
|
|
21
21
|
The actual implementation of `IsUnion`.
|
|
22
22
|
*/
|
|
23
23
|
type InternalIsUnion<T, U = T> =
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
) extends infer Result
|
|
24
|
+
(
|
|
25
|
+
IsNever<T> extends true
|
|
26
|
+
? false
|
|
27
|
+
: T extends any
|
|
28
|
+
? IsEqual<U, T> extends true
|
|
29
|
+
? false
|
|
30
|
+
: true
|
|
31
|
+
: never
|
|
32
|
+
) extends infer Result
|
|
33
33
|
// In some cases `Result` will return `false | true` which is `boolean`,
|
|
34
34
|
// that means `T` has at least two types and it's a union type,
|
|
35
35
|
// so we will return `true` instead of `boolean`.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
? boolean extends Result ? true
|
|
37
|
+
: Result
|
|
38
|
+
: never; // Should never happen
|
|
39
39
|
|
|
40
40
|
export {};
|
|
@@ -57,10 +57,10 @@ type Fruit = IterableElement<typeof fruits>;
|
|
|
57
57
|
@category Iterable
|
|
58
58
|
*/
|
|
59
59
|
export type IterableElement<TargetIterable> =
|
|
60
|
-
TargetIterable extends Iterable<infer ElementType>
|
|
61
|
-
ElementType
|
|
62
|
-
TargetIterable extends AsyncIterable<infer ElementType>
|
|
63
|
-
ElementType
|
|
64
|
-
never;
|
|
60
|
+
TargetIterable extends Iterable<infer ElementType>
|
|
61
|
+
? ElementType
|
|
62
|
+
: TargetIterable extends AsyncIterable<infer ElementType>
|
|
63
|
+
? ElementType
|
|
64
|
+
: never;
|
|
65
65
|
|
|
66
66
|
export {};
|
package/source/jsonify.d.ts
CHANGED
|
@@ -98,13 +98,13 @@ export type Jsonify<T> = IsAny<T> extends true
|
|
|
98
98
|
? null
|
|
99
99
|
: T extends JsonPrimitive
|
|
100
100
|
? T
|
|
101
|
-
|
|
102
|
-
T extends {toJSON(): infer J}
|
|
101
|
+
// Any object with toJSON is special case
|
|
102
|
+
: T extends {toJSON(): infer J}
|
|
103
103
|
? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
|
|
104
104
|
? J // Then T is Jsonable and its Jsonable value is J
|
|
105
105
|
: Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
|
|
106
|
-
|
|
107
|
-
T extends Number
|
|
106
|
+
// Instanced primitives are objects
|
|
107
|
+
: T extends Number
|
|
108
108
|
? number
|
|
109
109
|
: T extends String
|
|
110
110
|
? string
|
package/source/kebab-case.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type {KebabCase} from 'type-fest';
|
|
|
15
15
|
|
|
16
16
|
const someVariable: KebabCase<'fooBar'> = 'foo-bar';
|
|
17
17
|
const someVariableNoSplitOnNumbers: KebabCase<'p2pNetwork', {splitOnNumbers: false}> = 'p2p-network';
|
|
18
|
+
const someVariableWithPunctuation: KebabCase<'div.card::after', {splitOnPunctuation: true}> = 'div-card-after';
|
|
18
19
|
|
|
19
20
|
// Advanced
|
|
20
21
|
|
|
@@ -51,6 +51,13 @@ const splitOnNumbers: KebabCasedPropertiesDeep<{line1: {line2: [{line3: string}]
|
|
|
51
51
|
],
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
|
+
|
|
55
|
+
const splitOnPunctuation: KebabCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
|
|
56
|
+
'user-info': {
|
|
57
|
+
'user-id': 1,
|
|
58
|
+
'user-name': 'Tom',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
54
61
|
```
|
|
55
62
|
|
|
56
63
|
@category Change case
|
|
@@ -4,7 +4,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
|
|
|
4
4
|
import type {WordsOptions} from './words.d.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
Convert object properties to kebab case
|
|
7
|
+
Convert top-level object properties to kebab case.
|
|
8
8
|
|
|
9
9
|
This can be useful when, for example, converting some API types from a different style.
|
|
10
10
|
|
|
@@ -28,6 +28,10 @@ const result: KebabCasedProperties<User> = {
|
|
|
28
28
|
const splitOnNumbers: KebabCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
|
|
29
29
|
'line-1': 'string',
|
|
30
30
|
};
|
|
31
|
+
|
|
32
|
+
const splitOnPunctuation: KebabCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
|
|
33
|
+
'foo-bar': 'string',
|
|
34
|
+
};
|
|
31
35
|
```
|
|
32
36
|
|
|
33
37
|
@category Change case
|
|
@@ -38,7 +38,7 @@ type AllKeys = KeysOfUnion<Union>;
|
|
|
38
38
|
@category Object
|
|
39
39
|
*/
|
|
40
40
|
export type KeysOfUnion<ObjectType> =
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
// Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
|
|
42
|
+
keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
|
|
43
43
|
|
|
44
44
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {GreaterThan} from './greater-than.d.ts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
|
|
4
|
+
Returns a boolean for whether a given number is less than or equal to another number.
|
|
5
5
|
|
|
6
6
|
@example
|
|
7
7
|
```
|
|
@@ -16,9 +16,45 @@ type B = LessThanOrEqual<1, 1>;
|
|
|
16
16
|
type C = LessThanOrEqual<1, 5>;
|
|
17
17
|
//=> true
|
|
18
18
|
```
|
|
19
|
+
|
|
20
|
+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
|
|
21
|
+
|
|
22
|
+
@example
|
|
23
|
+
```
|
|
24
|
+
import type {LessThanOrEqual} from 'type-fest';
|
|
25
|
+
|
|
26
|
+
type A = LessThanOrEqual<number, 1>;
|
|
27
|
+
//=> boolean
|
|
28
|
+
|
|
29
|
+
type B = LessThanOrEqual<1, number>;
|
|
30
|
+
//=> boolean
|
|
31
|
+
|
|
32
|
+
type C = LessThanOrEqual<number, number>;
|
|
33
|
+
//=> boolean
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
@example
|
|
37
|
+
```
|
|
38
|
+
import type {LessThanOrEqual} from 'type-fest';
|
|
39
|
+
|
|
40
|
+
// Use `LessThanOrEqual` to constrain a function parameter to non-positive numbers.
|
|
41
|
+
declare function setNonPositive<N extends number>(value: LessThanOrEqual<N, 0> extends true ? N : never): void;
|
|
42
|
+
|
|
43
|
+
setNonPositive(0); // ✅ Allowed
|
|
44
|
+
setNonPositive(-1); // ✅ Allowed
|
|
45
|
+
|
|
46
|
+
// @ts-expect-error
|
|
47
|
+
setNonPositive(1);
|
|
48
|
+
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
setNonPositive(2);
|
|
51
|
+
```
|
|
19
52
|
*/
|
|
20
|
-
export type LessThanOrEqual<A extends number, B extends number> =
|
|
21
|
-
|
|
22
|
-
|
|
53
|
+
export type LessThanOrEqual<A extends number, B extends number> =
|
|
54
|
+
GreaterThan<A, B> extends infer Result
|
|
55
|
+
? Result extends true
|
|
56
|
+
? false
|
|
57
|
+
: true
|
|
58
|
+
: never; // Should never happen
|
|
23
59
|
|
|
24
60
|
export {};
|
package/source/less-than.d.ts
CHANGED
|
@@ -16,10 +16,42 @@ type B = LessThan<1, 1>;
|
|
|
16
16
|
type C = LessThan<1, 5>;
|
|
17
17
|
//=> true
|
|
18
18
|
```
|
|
19
|
+
|
|
20
|
+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
|
|
21
|
+
|
|
22
|
+
@example
|
|
23
|
+
```
|
|
24
|
+
import type {LessThan} from 'type-fest';
|
|
25
|
+
|
|
26
|
+
type A = LessThan<number, 1>;
|
|
27
|
+
//=> boolean
|
|
28
|
+
|
|
29
|
+
type B = LessThan<1, number>;
|
|
30
|
+
//=> boolean
|
|
31
|
+
|
|
32
|
+
type C = LessThan<number, number>;
|
|
33
|
+
//=> boolean
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
@example
|
|
37
|
+
```
|
|
38
|
+
import type {LessThan} from 'type-fest';
|
|
39
|
+
|
|
40
|
+
// Use `LessThan` to constrain a function parameter to negative numbers.
|
|
41
|
+
declare function setNegative<N extends number>(value: LessThan<N, 0> extends true ? N : never): void;
|
|
42
|
+
|
|
43
|
+
setNegative(-1); // ✅ Allowed
|
|
44
|
+
setNegative(-2); // ✅ Allowed
|
|
45
|
+
|
|
46
|
+
// @ts-expect-error
|
|
47
|
+
setNegative(0);
|
|
48
|
+
|
|
49
|
+
// @ts-expect-error
|
|
50
|
+
setNegative(1);
|
|
51
|
+
```
|
|
19
52
|
*/
|
|
20
|
-
export type LessThan<A extends number, B extends number> =
|
|
21
|
-
|
|
22
|
-
: GreaterThanOrEqual<A, B> extends infer Result
|
|
53
|
+
export type LessThan<A extends number, B extends number> =
|
|
54
|
+
GreaterThanOrEqual<A, B> extends infer Result
|
|
23
55
|
? Result extends true
|
|
24
56
|
? false
|
|
25
57
|
: true
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the
|
|
2
|
+
Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the [primitive type](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) it belongs to, or `never` if it's not a primitive.
|
|
3
3
|
|
|
4
4
|
Use-case: Working with generic types that may be literal types.
|
|
5
5
|
|
|
@@ -3,7 +3,7 @@ import type {Primitive} from './primitive.d.ts';
|
|
|
3
3
|
export type _LiteralStringUnion<T> = LiteralUnion<T, string>;
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
|
|
6
|
+
Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
|
|
7
7
|
|
|
8
8
|
Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
|
|
9
9
|
|
|
@@ -38,8 +38,8 @@ exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
|
|
|
38
38
|
@category Object
|
|
39
39
|
*/
|
|
40
40
|
export type MergeExclusive<FirstType, SecondType> =
|
|
41
|
-
(FirstType | SecondType) extends object
|
|
42
|
-
(Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType)
|
|
43
|
-
FirstType | SecondType;
|
|
41
|
+
(FirstType | SecondType) extends object
|
|
42
|
+
? (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType)
|
|
43
|
+
: FirstType | SecondType;
|
|
44
44
|
|
|
45
45
|
export {};
|
package/source/merge.d.ts
CHANGED
|
@@ -12,6 +12,31 @@ type SimpleMerge<Destination, Source> = Simplify<{
|
|
|
12
12
|
/**
|
|
13
13
|
Merge two types into a new type. Keys of the second type overrides keys of the first type.
|
|
14
14
|
|
|
15
|
+
This is different from the TypeScript `&` (intersection) operator. With `&`, conflicting property types are intersected, which often results in `never`. For example, `{a: string} & {a: number}` makes `a` become `string & number`, which resolves to `never`. With `Merge`, the second type's keys cleanly override the first, so `Merge<{a: string}, {a: number}>` gives `{a: number}` as expected. `Merge` also produces a flattened type (via `Simplify`), making it more readable in IDE tooltips compared to `A & B`.
|
|
16
|
+
|
|
17
|
+
@example
|
|
18
|
+
```
|
|
19
|
+
import type {Merge} from 'type-fest';
|
|
20
|
+
|
|
21
|
+
type Foo = {
|
|
22
|
+
a: string;
|
|
23
|
+
b: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type Bar = {
|
|
27
|
+
a: number; // Conflicts with Foo['a']
|
|
28
|
+
c: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// With `&`, `a` becomes `string & number` which is `never`. Not what you want.
|
|
32
|
+
type WithIntersection = (Foo & Bar)['a'];
|
|
33
|
+
//=> never
|
|
34
|
+
|
|
35
|
+
// With `Merge`, `a` is cleanly overridden to `number`.
|
|
36
|
+
type WithMerge = Merge<Foo, Bar>['a'];
|
|
37
|
+
//=> number
|
|
38
|
+
```
|
|
39
|
+
|
|
15
40
|
@example
|
|
16
41
|
```
|
|
17
42
|
import type {Merge} from 'type-fest';
|
|
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
|
|
|
4
4
|
type Recursive<T> = Array<Recursive<T>>;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
|
|
7
|
+
Create a type that represents a multidimensional array of the given type and dimension.
|
|
8
8
|
|
|
9
9
|
Use-cases:
|
|
10
10
|
- Return a n-dimensional array from functions.
|
|
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
|
|
|
4
4
|
type Recursive<T> = ReadonlyArray<Recursive<T>>;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
|
|
7
|
+
Create a type that represents a multidimensional readonly array of the given type and dimension.
|
|
8
8
|
|
|
9
9
|
Use-cases:
|
|
10
10
|
- Return a n-dimensional array from functions.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type {BuiltIns, HasMultipleCallSignatures} from './internal/type.d.ts';
|
|
2
|
+
import type {IsNever} from './is-never.d.ts';
|
|
3
|
+
import type {Simplify} from './simplify.d.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Recursively removes `null` and `undefined` from the specified type.
|
|
7
|
+
|
|
8
|
+
Use-cases:
|
|
9
|
+
- Normalizing data received from external sources where `null`/`undefined` have been cleaned.
|
|
10
|
+
- Creating non-nullable variants of deeply nested types.
|
|
11
|
+
|
|
12
|
+
NOTE: Optional modifiers (`?`) are not removed from properties. For example, `NonNullableDeep<{foo?: string | null | undefined}>` will result in `{foo?: string}`. To remove both optional modifiers and nullables, use {@link RequiredDeep} in conjunction with this type.
|
|
13
|
+
|
|
14
|
+
@example
|
|
15
|
+
```
|
|
16
|
+
import type {NonNullableDeep} from 'type-fest';
|
|
17
|
+
|
|
18
|
+
type UserDraft = {
|
|
19
|
+
name: string | null;
|
|
20
|
+
address: {
|
|
21
|
+
city: string | undefined;
|
|
22
|
+
postalCode: string | null;
|
|
23
|
+
landmark?: string | undefined;
|
|
24
|
+
};
|
|
25
|
+
tags: Array<string | null>;
|
|
26
|
+
visits: Map<string | null, {
|
|
27
|
+
date: Date | null;
|
|
28
|
+
notes: Set<string | undefined>;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type User = NonNullableDeep<UserDraft>;
|
|
33
|
+
//=> {
|
|
34
|
+
// name: string;
|
|
35
|
+
// address: {
|
|
36
|
+
// city: string;
|
|
37
|
+
// postalCode: string;
|
|
38
|
+
// landmark?: string;
|
|
39
|
+
// };
|
|
40
|
+
// tags: string[];
|
|
41
|
+
// visits: Map<string, {
|
|
42
|
+
// date: Date;
|
|
43
|
+
// notes: Set<string>;
|
|
44
|
+
// }>;
|
|
45
|
+
// }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
@example
|
|
49
|
+
```
|
|
50
|
+
import type {NonNullableDeep} from 'type-fest';
|
|
51
|
+
|
|
52
|
+
type ArrayExample = NonNullableDeep<[{a: number | undefined}, ...Array<{b: string | null}>]>;
|
|
53
|
+
//=> [{a: number}, ...{b: string}[]]
|
|
54
|
+
|
|
55
|
+
type MapExample = NonNullableDeep<{a: Map<{a: string | null}, {c: number | undefined}>}>;
|
|
56
|
+
//=> {a: Map<{a: string}, {c: number}>}
|
|
57
|
+
|
|
58
|
+
type SetExample = NonNullableDeep<Set<{a: string | null}> | null | undefined>;
|
|
59
|
+
//=> Set<{a: string}>
|
|
60
|
+
|
|
61
|
+
type PromiseExample = NonNullableDeep<{a: Promise<{b: string | null}>}>;
|
|
62
|
+
//=> {a: Promise<{b: string}>}
|
|
63
|
+
|
|
64
|
+
type FunctionExample = NonNullableDeep<(a: string | null) => number | undefined>;
|
|
65
|
+
//=> (a: string) => number
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
@category Utilities
|
|
69
|
+
@category Object
|
|
70
|
+
@category Array
|
|
71
|
+
@category Set
|
|
72
|
+
@category Map
|
|
73
|
+
*/
|
|
74
|
+
export type NonNullableDeep<T> =
|
|
75
|
+
T extends BuiltIns | (new (...arguments_: any[]) => unknown)
|
|
76
|
+
? Exclude<T, null | undefined> // `Exclude` is used instead of `NonNullable` because `NonNullable<void>` results in `void & {}`.
|
|
77
|
+
: T extends Map<infer KeyType, infer ValueType>
|
|
78
|
+
? Map<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
|
|
79
|
+
: T extends Set<infer ItemType>
|
|
80
|
+
? Set<NonNullableDeep<ItemType>>
|
|
81
|
+
: T extends ReadonlyMap<infer KeyType, infer ValueType>
|
|
82
|
+
? ReadonlyMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
|
|
83
|
+
: T extends ReadonlySet<infer ItemType>
|
|
84
|
+
? ReadonlySet<NonNullableDeep<ItemType>>
|
|
85
|
+
: T extends WeakMap<infer KeyType, infer ValueType>
|
|
86
|
+
? WeakMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
|
|
87
|
+
: T extends WeakSet<infer ItemType>
|
|
88
|
+
? WeakSet<NonNullableDeep<ItemType>>
|
|
89
|
+
: T extends Promise<infer ValueType>
|
|
90
|
+
? Promise<NonNullableDeep<ValueType>>
|
|
91
|
+
: T extends (...arguments_: any[]) => unknown
|
|
92
|
+
? HasMultipleCallSignatures<T> extends true
|
|
93
|
+
? T
|
|
94
|
+
: ((...arguments_: NonNullableDeep<Parameters<T>>) => NonNullableDeep<ReturnType<T>>)
|
|
95
|
+
& (IsNever<keyof T> extends true
|
|
96
|
+
? unknown
|
|
97
|
+
: NonNullableDeep<Simplify<T>>) // `Simplify` removes the call signature
|
|
98
|
+
: T extends object
|
|
99
|
+
? {[P in keyof T]: NonNullableDeep<T[P]>}
|
|
100
|
+
: unknown;
|
|
101
|
+
|
|
102
|
+
export {};
|
package/source/numeric.d.ts
CHANGED
|
@@ -121,9 +121,9 @@ declare function setPercentage<T extends number>(length: Float<T>): void;
|
|
|
121
121
|
@category Numeric
|
|
122
122
|
*/
|
|
123
123
|
export type Float<T> =
|
|
124
|
-
T extends unknown // To distributive type
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
T extends unknown // To distributive type
|
|
125
|
+
? IsFloat<T> extends true ? T : never
|
|
126
|
+
: never; // Never happens
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
129
|
A negative (`-∞ < x < 0`) `number` that is not an integer.
|