@depup/type-fest 5.4.4-depup.0 → 5.9.0-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 +2 -2
- package/changes.json +5 -0
- package/index.d.ts +23 -8
- package/package.json +17 -11
- package/readme.md +98 -64
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +8 -7
- 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-reverse.d.ts +4 -3
- package/source/array-splice.d.ts +26 -26
- package/source/array-tail.d.ts +4 -4
- 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-keys.d.ts +1 -1
- package/source/conditional-pick-deep.d.ts +5 -3
- package/source/conditional-pick.d.ts +6 -4
- package/source/delimiter-case.d.ts +11 -9
- 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/exclude-rest-element.d.ts +4 -4
- package/source/exclusify-union.d.ts +4 -4
- package/source/extends-strict.d.ts +129 -22
- package/source/extract-exactly.d.ts +56 -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 +8 -15
- package/source/internal/keys.d.ts +9 -9
- package/source/internal/numeric.d.ts +19 -27
- package/source/internal/object.d.ts +44 -6
- package/source/internal/string.d.ts +1 -76
- package/source/internal/tuple.d.ts +3 -3
- package/source/internal/type.d.ts +16 -9
- package/source/is-boolean-literal.d.ts +39 -0
- package/source/is-equal.d.ts +0 -1
- package/source/is-integer.d.ts +8 -8
- package/source/is-literal.d.ts +43 -267
- package/source/is-numeric-literal.d.ts +50 -0
- package/source/is-string-literal.d.ts +72 -0
- package/source/is-symbol-literal.d.ts +39 -0
- package/source/is-union.d.ts +12 -12
- package/source/iterable-element.d.ts +5 -5
- package/source/jsonify.d.ts +5 -9
- 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/last-array-element.d.ts +66 -13
- 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/object-merge.d.ts +21 -16
- 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 +16 -34
- package/source/remove-suffix.d.ts +114 -0
- package/source/rename-keys.d.ts +163 -0
- package/source/replace.d.ts +2 -2
- package/source/require-all-or-none.d.ts +5 -5
- package/source/require-at-least-one.d.ts +9 -11
- package/source/require-exactly-one.d.ts +7 -7
- package/source/require-one-or-none.d.ts +5 -5
- package/source/required-deep.d.ts +3 -1
- package/source/schema.d.ts +16 -8
- package/source/screaming-snake-case.d.ts +1 -0
- package/source/set-non-nullable-deep.d.ts +8 -4
- 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 +3 -2
- package/source/set-required.d.ts +4 -8
- package/source/shared-union-fields-deep.d.ts +5 -4
- 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 +115 -0
- package/source/split-on-rest-element.d.ts +6 -4
- package/source/split.d.ts +1 -1
- package/source/spread.d.ts +1 -5
- package/source/string-length.d.ts +38 -0
- package/source/string-repeat.d.ts +48 -21
- package/source/string-slice.d.ts +1 -1
- package/source/string-to-array.d.ts +97 -0
- package/source/string-to-number.d.ts +67 -0
- 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 +40 -8
- package/source/tuple-of.d.ts +42 -8
- package/source/typed-array.d.ts +1 -0
- 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/unwrap-required.d.ts +37 -0
- package/source/words.d.ts +30 -4
- package/source/writable.d.ts +15 -19
- package/source/xor.d.ts +1 -1
|
@@ -3,13 +3,14 @@ import type {IsEqual} from '../is-equal.d.ts';
|
|
|
3
3
|
import type {KeysOfUnion} from '../keys-of-union.d.ts';
|
|
4
4
|
import type {RequiredKeysOf} from '../required-keys-of.d.ts';
|
|
5
5
|
import type {Merge} from '../merge.d.ts';
|
|
6
|
-
import type {OptionalKeysOf} from '../optional-keys-of.d.ts';
|
|
7
6
|
import type {IsAny} from '../is-any.d.ts';
|
|
8
7
|
import type {If} from '../if.d.ts';
|
|
9
8
|
import type {IsNever} from '../is-never.d.ts';
|
|
9
|
+
import type {StringToNumber} from '../string-to-number.d.ts';
|
|
10
|
+
import type {Primitive} from '../primitive.d.ts';
|
|
10
11
|
import type {FilterDefinedKeys, FilterOptionalKeys} from './keys.d.ts';
|
|
11
|
-
import type {MapsSetsOrArrays, NonRecursiveType} from './type.d.ts';
|
|
12
|
-
import type {
|
|
12
|
+
import type {IfNotAnyOrNever, MapsSetsOrArrays, NonRecursiveType} from './type.d.ts';
|
|
13
|
+
import type {ToString} from './string.d.ts';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
Create an object type with the given key `<Key>` and value `<Value>`.
|
|
@@ -223,14 +224,23 @@ export type ApplyDefaultOptions<
|
|
|
223
224
|
Options extends object,
|
|
224
225
|
Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>,
|
|
225
226
|
SpecifiedOptions extends Options,
|
|
227
|
+
> =
|
|
228
|
+
_ApplyDefaultOptions<Options, Defaults, SpecifiedOptions> extends infer Result extends Required<Options> // `extends Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
|
|
229
|
+
? Result
|
|
230
|
+
: never;
|
|
231
|
+
|
|
232
|
+
type _ApplyDefaultOptions<
|
|
233
|
+
Options,
|
|
234
|
+
Defaults,
|
|
235
|
+
SpecifiedOptions,
|
|
226
236
|
> =
|
|
227
237
|
If<IsAny<SpecifiedOptions>, Defaults,
|
|
228
238
|
If<IsNever<SpecifiedOptions>, Defaults,
|
|
229
|
-
|
|
239
|
+
Merge<Defaults, {
|
|
230
240
|
[Key in keyof SpecifiedOptions
|
|
231
|
-
as
|
|
241
|
+
as undefined extends Required<Options>[Key & keyof Options] ? Key : undefined extends SpecifiedOptions[Key] ? never : Key
|
|
232
242
|
]: SpecifiedOptions[Key]
|
|
233
|
-
}
|
|
243
|
+
}>>>;
|
|
234
244
|
|
|
235
245
|
/**
|
|
236
246
|
Collapses literal types in a union into their corresponding primitive types, when possible. For example, `CollapseLiterals<'foo' | 'bar' | (string & {})>` returns `string`.
|
|
@@ -265,6 +275,34 @@ export type CollapseLiterals<T> = {} extends T
|
|
|
265
275
|
? U
|
|
266
276
|
: T;
|
|
267
277
|
|
|
278
|
+
/**
|
|
279
|
+
Returns the base type of a branded type.
|
|
280
|
+
|
|
281
|
+
@example
|
|
282
|
+
```
|
|
283
|
+
type Brand = {readonly __brand: unique symbol};
|
|
284
|
+
|
|
285
|
+
type A = UnwrapBrand<string & Brand>;
|
|
286
|
+
//=> string
|
|
287
|
+
|
|
288
|
+
type B = UnwrapBrand<number & Brand>;
|
|
289
|
+
//=> number
|
|
290
|
+
|
|
291
|
+
type C = UnwrapBrand<PropertyKey & Brand>;
|
|
292
|
+
//=> PropertyKey
|
|
293
|
+
|
|
294
|
+
type D = UnwrapBrand<(1 | 200n | 'foo' | 'bar') & Brand>;
|
|
295
|
+
//=> 1 | 200n | 'foo' | 'bar'
|
|
296
|
+
```
|
|
297
|
+
*/
|
|
298
|
+
export type UnwrapBrand<T> = IfNotAnyOrNever<T, {ifNot: _UnwrapBrand<T, Primitive>}>;
|
|
299
|
+
|
|
300
|
+
type _UnwrapBrand<T, Base> = T extends Primitive
|
|
301
|
+
? T extends infer U & Pick<T, Exclude<keyof T, KeysOfUnion<Base>>>
|
|
302
|
+
? U
|
|
303
|
+
: T
|
|
304
|
+
: T;
|
|
305
|
+
|
|
268
306
|
/**
|
|
269
307
|
Normalize keys by including string and number representations wherever applicable.
|
|
270
308
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {TupleOf} from '../tuple-of.d.ts';
|
|
2
|
-
import type {NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
|
|
3
2
|
import type {Trim} from '../trim.d.ts';
|
|
3
|
+
import type {StringLength} from '../string-length.d.ts';
|
|
4
4
|
import type {Whitespace} from './characters.d.ts';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -10,42 +10,6 @@ Note: This type is not the return type of the `.toString()` function.
|
|
|
10
10
|
*/
|
|
11
11
|
export type ToString<T> = T extends string | number ? `${T}` : never;
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
Converts a numeric string to a number.
|
|
15
|
-
|
|
16
|
-
@example
|
|
17
|
-
```
|
|
18
|
-
type PositiveInt = StringToNumber<'1234'>;
|
|
19
|
-
//=> 1234
|
|
20
|
-
|
|
21
|
-
type NegativeInt = StringToNumber<'-1234'>;
|
|
22
|
-
//=> -1234
|
|
23
|
-
|
|
24
|
-
type PositiveFloat = StringToNumber<'1234.56'>;
|
|
25
|
-
//=> 1234.56
|
|
26
|
-
|
|
27
|
-
type NegativeFloat = StringToNumber<'-1234.56'>;
|
|
28
|
-
//=> -1234.56
|
|
29
|
-
|
|
30
|
-
type PositiveInfinity = StringToNumber<'Infinity'>;
|
|
31
|
-
//=> Infinity
|
|
32
|
-
|
|
33
|
-
type NegativeInfinity = StringToNumber<'-Infinity'>;
|
|
34
|
-
//=> -Infinity
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
@category String
|
|
38
|
-
@category Numeric
|
|
39
|
-
@category Template literal
|
|
40
|
-
*/
|
|
41
|
-
export type StringToNumber<S extends string> = S extends `${infer N extends number}`
|
|
42
|
-
? N
|
|
43
|
-
: S extends 'Infinity'
|
|
44
|
-
? PositiveInfinity
|
|
45
|
-
: S extends '-Infinity'
|
|
46
|
-
? NegativeInfinity
|
|
47
|
-
: never;
|
|
48
|
-
|
|
49
13
|
/**
|
|
50
14
|
Returns a boolean for whether the given string `S` starts with the given string `SearchString`.
|
|
51
15
|
|
|
@@ -73,45 +37,6 @@ export type StartsWith<S extends string, SearchString extends string> = string e
|
|
|
73
37
|
? true
|
|
74
38
|
: false;
|
|
75
39
|
|
|
76
|
-
/**
|
|
77
|
-
Returns an array of the characters of the string.
|
|
78
|
-
|
|
79
|
-
@example
|
|
80
|
-
```
|
|
81
|
-
type A = StringToArray<'abcde'>;
|
|
82
|
-
//=> ['a', 'b', 'c', 'd', 'e']
|
|
83
|
-
|
|
84
|
-
type B = StringToArray<string>;
|
|
85
|
-
//=> never
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
@category String
|
|
89
|
-
*/
|
|
90
|
-
export type StringToArray<S extends string, Result extends string[] = []> = string extends S
|
|
91
|
-
? never
|
|
92
|
-
: S extends `${infer F}${infer R}`
|
|
93
|
-
? StringToArray<R, [...Result, F]>
|
|
94
|
-
: Result;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
Returns the length of the given string.
|
|
98
|
-
|
|
99
|
-
@example
|
|
100
|
-
```
|
|
101
|
-
type A = StringLength<'abcde'>;
|
|
102
|
-
//=> 5
|
|
103
|
-
|
|
104
|
-
type B = StringLength<string>;
|
|
105
|
-
//=> never
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
@category String
|
|
109
|
-
@category Template literal
|
|
110
|
-
*/
|
|
111
|
-
export type StringLength<S extends string> = string extends S
|
|
112
|
-
? never
|
|
113
|
-
: StringToArray<S>['length'];
|
|
114
|
-
|
|
115
40
|
/**
|
|
116
41
|
Returns a boolean for whether a string is whitespace.
|
|
117
42
|
*/
|
|
@@ -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>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {If} from '../if.d.ts';
|
|
2
1
|
import type {IsAny} from '../is-any.d.ts';
|
|
3
2
|
import type {IsNever} from '../is-never.d.ts';
|
|
4
3
|
import type {Primitive} from '../primitive.d.ts';
|
|
@@ -90,16 +89,16 @@ An if-else-like type that resolves depending on whether the given type is `any`
|
|
|
90
89
|
|
|
91
90
|
@example
|
|
92
91
|
```
|
|
93
|
-
// When `T` is
|
|
94
|
-
type A = IfNotAnyOrNever<string, 'VALID'
|
|
92
|
+
// When `T` is neither `any` nor `never` (like `string`) => Returns `IfNot` branch
|
|
93
|
+
type A = IfNotAnyOrNever<string, {ifNot: 'VALID'; ifAny: 'IS_ANY'; ifNever: 'IS_NEVER'}>;
|
|
95
94
|
//=> 'VALID'
|
|
96
95
|
|
|
97
96
|
// When `T` is `any` => Returns `IfAny` branch
|
|
98
|
-
type B = IfNotAnyOrNever<any, 'VALID'
|
|
97
|
+
type B = IfNotAnyOrNever<any, {ifNot: 'VALID'; ifAny: 'IS_ANY'; ifNever: 'IS_NEVER'}>;
|
|
99
98
|
//=> 'IS_ANY'
|
|
100
99
|
|
|
101
100
|
// When `T` is `never` => Returns `IfNever` branch
|
|
102
|
-
type C = IfNotAnyOrNever<never, 'VALID'
|
|
101
|
+
type C = IfNotAnyOrNever<never, {ifNot: 'VALID'; ifAny: 'IS_ANY'; ifNever: 'IS_NEVER'}>;
|
|
103
102
|
//=> 'IS_NEVER'
|
|
104
103
|
```
|
|
105
104
|
|
|
@@ -112,7 +111,7 @@ import type {StringRepeat} from 'type-fest';
|
|
|
112
111
|
type NineHundredNinetyNineSpaces = StringRepeat<' ', 999>;
|
|
113
112
|
|
|
114
113
|
// The following implementation is not tail recursive
|
|
115
|
-
type TrimLeft<S extends string> = IfNotAnyOrNever<S, S extends ` ${infer R}` ? TrimLeft<R> : S>;
|
|
114
|
+
type TrimLeft<S extends string> = IfNotAnyOrNever<S, {ifNot: S extends ` ${infer R}` ? TrimLeft<R> : S}>;
|
|
116
115
|
|
|
117
116
|
// Hence, instantiations with long strings will fail
|
|
118
117
|
// @ts-expect-error
|
|
@@ -121,7 +120,7 @@ type T1 = TrimLeft<NineHundredNinetyNineSpaces>;
|
|
|
121
120
|
// Error: Type instantiation is excessively deep and possibly infinite.
|
|
122
121
|
|
|
123
122
|
// To fix this, move the recursion into a helper type
|
|
124
|
-
type TrimLeftOptimised<S extends string> = IfNotAnyOrNever<S, _TrimLeftOptimised<S
|
|
123
|
+
type TrimLeftOptimised<S extends string> = IfNotAnyOrNever<S, {ifNot: _TrimLeftOptimised<S>}>;
|
|
125
124
|
|
|
126
125
|
type _TrimLeftOptimised<S extends string> = S extends ` ${infer R}` ? _TrimLeftOptimised<R> : S;
|
|
127
126
|
|
|
@@ -129,8 +128,16 @@ type T2 = TrimLeftOptimised<NineHundredNinetyNineSpaces>;
|
|
|
129
128
|
//=> ''
|
|
130
129
|
```
|
|
131
130
|
*/
|
|
132
|
-
export type IfNotAnyOrNever<T,
|
|
133
|
-
|
|
131
|
+
export type IfNotAnyOrNever<T, Cases extends {ifNot: unknown; ifAny?: unknown; ifNever?: unknown}> =
|
|
132
|
+
IsAny<T> extends true
|
|
133
|
+
? 'ifAny' extends keyof Cases
|
|
134
|
+
? Cases['ifAny']
|
|
135
|
+
: any
|
|
136
|
+
: IsNever<T> extends true
|
|
137
|
+
? 'ifNever' extends keyof Cases
|
|
138
|
+
? Cases['ifNever']
|
|
139
|
+
: never
|
|
140
|
+
: Cases['ifNot'];
|
|
134
141
|
|
|
135
142
|
/**
|
|
136
143
|
Returns a boolean for whether the given type is `any` or `never`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type {CollapseLiterals, UnwrapBrand} from './internal/object.d.ts';
|
|
2
|
+
import type {IfNotAnyOrNever} from './internal/type.d.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
import type {IsBooleanLiteral} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
type A = IsBooleanLiteral<true>;
|
|
12
|
+
//=> true
|
|
13
|
+
|
|
14
|
+
type B = IsBooleanLiteral<false>;
|
|
15
|
+
//=> true
|
|
16
|
+
|
|
17
|
+
type C = IsBooleanLiteral<boolean>;
|
|
18
|
+
//=> false
|
|
19
|
+
|
|
20
|
+
type D = IsBooleanLiteral<true | false>;
|
|
21
|
+
//=> false
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
@category Type Guard
|
|
25
|
+
@category Utilities
|
|
26
|
+
*/
|
|
27
|
+
export type IsBooleanLiteral<T> = IfNotAnyOrNever<T, {
|
|
28
|
+
ifNot: _IsBooleanLiteral<CollapseLiterals<UnwrapBrand<T>>>;
|
|
29
|
+
ifAny: false;
|
|
30
|
+
ifNever: false;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
type _IsBooleanLiteral<T> = boolean extends T
|
|
34
|
+
? false
|
|
35
|
+
: T extends boolean
|
|
36
|
+
? true
|
|
37
|
+
: false;
|
|
38
|
+
|
|
39
|
+
export {};
|
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
|
@@ -1,270 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import type {IsStringLiteral} from './is-string-literal.d.ts';
|
|
2
|
+
import type {IsNumericLiteral} from './is-numeric-literal.d.ts';
|
|
3
|
+
import type {IsBooleanLiteral} from './is-boolean-literal.d.ts';
|
|
4
|
+
import type {IsSymbolLiteral} from './is-symbol-literal.d.ts';
|
|
4
5
|
import type {IsNever} from './is-never.d.ts';
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
Returns a boolean for whether the given type `T` is the specified `LiteralType`.
|
|
9
|
-
|
|
10
|
-
@link https://stackoverflow.com/a/52806744/10292952
|
|
11
|
-
|
|
12
|
-
@example
|
|
13
|
-
```
|
|
14
|
-
type A = LiteralCheck<1, number>;
|
|
15
|
-
//=> true
|
|
16
|
-
|
|
17
|
-
type B = LiteralCheck<number, number>;
|
|
18
|
-
//=> false
|
|
19
|
-
|
|
20
|
-
type C = LiteralCheck<1, string>;
|
|
21
|
-
//=> false
|
|
22
|
-
```
|
|
23
|
-
*/
|
|
24
|
-
type LiteralCheck<T, LiteralType extends Primitive> = (
|
|
25
|
-
IsNever<T> extends false // Must be wider than `never`
|
|
26
|
-
? [T] extends [LiteralType & infer U] // Remove any branding
|
|
27
|
-
? [U] extends [LiteralType] // Must be narrower than `LiteralType`
|
|
28
|
-
? [LiteralType] extends [U] // Cannot be wider than `LiteralType`
|
|
29
|
-
? false
|
|
30
|
-
: true
|
|
31
|
-
: false
|
|
32
|
-
: false
|
|
33
|
-
: false
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
Returns a boolean for whether the given type `T` is one of the specified literal types in `LiteralUnionType`.
|
|
38
|
-
|
|
39
|
-
@example
|
|
40
|
-
```
|
|
41
|
-
type A = LiteralChecks<1, Numeric>;
|
|
42
|
-
//=> true
|
|
43
|
-
|
|
44
|
-
type B = LiteralChecks<1n, Numeric>;
|
|
45
|
-
//=> true
|
|
46
|
-
|
|
47
|
-
type C = LiteralChecks<bigint, Numeric>;
|
|
48
|
-
//=> false
|
|
49
|
-
```
|
|
50
|
-
*/
|
|
51
|
-
type LiteralChecks<T, LiteralUnionType> = (
|
|
52
|
-
// Conditional type to force union distribution.
|
|
53
|
-
// If `T` is none of the literal types in the union `LiteralUnionType`, then `LiteralCheck<T, LiteralType>` will evaluate to `false` for the whole union.
|
|
54
|
-
// If `T` is one of the literal types in the union, it will evaluate to `boolean` (i.e. `true | false`)
|
|
55
|
-
IsNotFalse<LiteralUnionType extends Primitive
|
|
56
|
-
? LiteralCheck<T, LiteralUnionType>
|
|
57
|
-
: never
|
|
58
|
-
>
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
63
|
-
|
|
64
|
-
Useful for:
|
|
65
|
-
- providing strongly-typed string manipulation functions
|
|
66
|
-
- constraining strings to be a string literal
|
|
67
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
68
|
-
|
|
69
|
-
The implementation of this type is inspired by the trick mentioned in this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
|
|
70
|
-
|
|
71
|
-
@example
|
|
72
|
-
```
|
|
73
|
-
import type {IsStringLiteral} from 'type-fest';
|
|
74
|
-
|
|
75
|
-
type CapitalizedString<T extends string> = IsStringLiteral<T> extends true ? Capitalize<T> : string;
|
|
76
|
-
|
|
77
|
-
// https://github.com/yankeeinlondon/native-dash/blob/master/src/capitalize.ts
|
|
78
|
-
function capitalize<T extends Readonly<string>>(input: T): CapitalizedString<T> {
|
|
79
|
-
return (input.slice(0, 1).toUpperCase() + input.slice(1)) as CapitalizedString<T>;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const output = capitalize('hello, world!');
|
|
83
|
-
//=> 'Hello, world!'
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
@example
|
|
87
|
-
```
|
|
88
|
-
// String types with infinite set of possible values return `false`.
|
|
89
|
-
|
|
90
|
-
import type {IsStringLiteral} from 'type-fest';
|
|
91
|
-
|
|
92
|
-
type AllUppercaseStrings = IsStringLiteral<Uppercase<string>>;
|
|
93
|
-
//=> false
|
|
94
|
-
|
|
95
|
-
type StringsStartingWithOn = IsStringLiteral<`on${string}`>;
|
|
96
|
-
//=> false
|
|
97
|
-
|
|
98
|
-
// This behaviour is particularly useful in string manipulation utilities, as infinite string types often require separate handling.
|
|
99
|
-
|
|
100
|
-
type Length<S extends string, Counter extends never[] = []> =
|
|
101
|
-
IsStringLiteral<S> extends false
|
|
102
|
-
? number // return `number` for infinite string types
|
|
103
|
-
: S extends `${string}${infer Tail}`
|
|
104
|
-
? Length<Tail, [...Counter, never]>
|
|
105
|
-
: Counter['length'];
|
|
106
|
-
|
|
107
|
-
type L1 = Length<Lowercase<string>>;
|
|
108
|
-
//=> number
|
|
109
|
-
|
|
110
|
-
type L2 = Length<`${number}`>;
|
|
111
|
-
//=> number
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
@category Type Guard
|
|
115
|
-
@category Utilities
|
|
116
|
-
*/
|
|
117
|
-
export type IsStringLiteral<S> = IfNotAnyOrNever<S,
|
|
118
|
-
_IsStringLiteral<CollapseLiterals<S extends TagContainer<any> ? UnwrapTagged<S> : S>>,
|
|
119
|
-
false, false>;
|
|
120
|
-
|
|
121
|
-
export type _IsStringLiteral<S> =
|
|
122
|
-
// If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
|
|
123
|
-
// and since `{}` extends index signatures, the result becomes `false`.
|
|
124
|
-
S extends string
|
|
125
|
-
? {} extends Record<S, never>
|
|
126
|
-
? false
|
|
127
|
-
: true
|
|
128
|
-
: false;
|
|
129
|
-
|
|
130
|
-
/**
|
|
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).
|
|
132
|
-
|
|
133
|
-
Useful for:
|
|
134
|
-
- providing strongly-typed functions when given literal arguments
|
|
135
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
136
|
-
|
|
137
|
-
@example
|
|
138
|
-
```
|
|
139
|
-
import type {IsNumericLiteral, IsStringLiteral} from 'type-fest';
|
|
140
|
-
|
|
141
|
-
// https://github.com/inocan-group/inferred-types/blob/master/modules/types/src/boolean-logic/operators/EndsWith.ts
|
|
142
|
-
type EndsWith<TValue, TEndsWith extends string> =
|
|
143
|
-
TValue extends string
|
|
144
|
-
? IsStringLiteral<TEndsWith> extends true
|
|
145
|
-
? IsStringLiteral<TValue> extends true
|
|
146
|
-
? TValue extends `${string}${TEndsWith}`
|
|
147
|
-
? true
|
|
148
|
-
: false
|
|
149
|
-
: boolean
|
|
150
|
-
: boolean
|
|
151
|
-
: TValue extends number
|
|
152
|
-
? IsNumericLiteral<TValue> extends true
|
|
153
|
-
? EndsWith<`${TValue}`, TEndsWith>
|
|
154
|
-
: false
|
|
155
|
-
: false;
|
|
156
|
-
|
|
157
|
-
function endsWith<Input extends string | number, End extends string>(input: Input, end: End) {
|
|
158
|
-
return `${input}`.endsWith(end) as EndsWith<Input, End>;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
endsWith('abc', 'c');
|
|
162
|
-
//=> true
|
|
163
|
-
|
|
164
|
-
endsWith(123_456, '456');
|
|
165
|
-
//=> true
|
|
166
|
-
|
|
167
|
-
const end = '123' as string;
|
|
168
|
-
|
|
169
|
-
endsWith('abc123', end);
|
|
170
|
-
//=> boolean
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
@category Type Guard
|
|
174
|
-
@category Utilities
|
|
175
|
-
*/
|
|
176
|
-
export type IsNumericLiteral<T> = LiteralChecks<T, _Numeric>;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
180
|
-
|
|
181
|
-
Useful for:
|
|
182
|
-
- providing strongly-typed functions when given literal arguments
|
|
183
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
184
|
-
|
|
185
|
-
@example
|
|
186
|
-
```
|
|
187
|
-
import type {IsBooleanLiteral} from 'type-fest';
|
|
188
|
-
|
|
189
|
-
const id = 123;
|
|
190
|
-
|
|
191
|
-
type GetId<AsString extends boolean> =
|
|
192
|
-
IsBooleanLiteral<AsString> extends true
|
|
193
|
-
? AsString extends true
|
|
194
|
-
? `${typeof id}`
|
|
195
|
-
: typeof id
|
|
196
|
-
: number | string;
|
|
197
|
-
|
|
198
|
-
function getId<AsString extends boolean = false>(options?: {asString: AsString}) {
|
|
199
|
-
return (options?.asString ? `${id}` : id) as GetId<AsString>;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const numberId = getId();
|
|
203
|
-
//=> 123
|
|
204
|
-
|
|
205
|
-
const stringId = getId({asString: true});
|
|
206
|
-
//=> '123'
|
|
207
|
-
|
|
208
|
-
declare const runtimeBoolean: boolean;
|
|
209
|
-
const eitherId = getId({asString: runtimeBoolean});
|
|
210
|
-
//=> string | number
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
@category Type Guard
|
|
214
|
-
@category Utilities
|
|
215
|
-
*/
|
|
216
|
-
export type IsBooleanLiteral<T> = LiteralCheck<T, boolean>;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
220
|
-
|
|
221
|
-
Useful for:
|
|
222
|
-
- providing strongly-typed functions when given literal arguments
|
|
223
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
224
|
-
|
|
225
|
-
@example
|
|
226
|
-
```
|
|
227
|
-
import type {IsSymbolLiteral} from 'type-fest';
|
|
228
|
-
|
|
229
|
-
type Get<Object_ extends Record<symbol, number>, Key extends keyof Object_> =
|
|
230
|
-
IsSymbolLiteral<Key> extends true
|
|
231
|
-
? Object_[Key]
|
|
232
|
-
: number;
|
|
233
|
-
|
|
234
|
-
function get<Object_ extends Record<symbol, number>, Key extends keyof Object_>(o: Object_, key: Key) {
|
|
235
|
-
return o[key] as Get<Object_, Key>;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const symbolLiteral = Symbol('literal');
|
|
239
|
-
let symbolValue = Symbol('value1');
|
|
240
|
-
symbolValue = Symbol('value2');
|
|
241
|
-
|
|
242
|
-
get({[symbolLiteral]: 1} as const, symbolLiteral);
|
|
243
|
-
//=> 1
|
|
244
|
-
|
|
245
|
-
get({[symbolValue]: 1} as const, symbolValue);
|
|
246
|
-
//=> number
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
@category Type Guard
|
|
250
|
-
@category Utilities
|
|
251
|
-
*/
|
|
252
|
-
export type IsSymbolLiteral<T> = LiteralCheck<T, symbol>;
|
|
253
|
-
|
|
254
|
-
/** Helper type for `IsLiteral`. */
|
|
255
|
-
type IsLiteralUnion<T> =
|
|
256
|
-
| IsStringLiteral<T>
|
|
257
|
-
| IsNumericLiteral<T>
|
|
258
|
-
| IsBooleanLiteral<T>
|
|
259
|
-
| IsSymbolLiteral<T>;
|
|
6
|
+
import type {IfNotAnyOrNever} from './internal/type.d.ts';
|
|
7
|
+
import type {CollapseLiterals, UnwrapBrand} from './internal/object.d.ts';
|
|
260
8
|
|
|
261
9
|
/**
|
|
262
10
|
Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
263
11
|
|
|
264
|
-
Useful for:
|
|
265
|
-
- providing strongly-typed functions when given literal arguments
|
|
266
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
267
|
-
|
|
268
12
|
@example
|
|
269
13
|
```
|
|
270
14
|
import type {IsLiteral} from 'type-fest';
|
|
@@ -300,16 +44,48 @@ type I = IsLiteral<symbol>;
|
|
|
300
44
|
type J = IsLiteral<true>;
|
|
301
45
|
//=> true
|
|
302
46
|
|
|
303
|
-
type K = IsLiteral<
|
|
47
|
+
type K = IsLiteral<false>;
|
|
48
|
+
//=> true
|
|
49
|
+
|
|
50
|
+
type L = IsLiteral<boolean>;
|
|
304
51
|
//=> false
|
|
52
|
+
|
|
53
|
+
type M = IsLiteral<1 | 'foo' | false>;
|
|
54
|
+
//=> true
|
|
55
|
+
|
|
56
|
+
type N = IsLiteral<string | number | symbol>;
|
|
57
|
+
//=> false
|
|
58
|
+
|
|
59
|
+
type O = IsLiteral<1000n | string | true>;
|
|
60
|
+
//=> boolean
|
|
305
61
|
```
|
|
306
62
|
|
|
307
63
|
@category Type Guard
|
|
308
64
|
@category Utilities
|
|
309
65
|
*/
|
|
310
|
-
export type IsLiteral<T> =
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
66
|
+
export type IsLiteral<T> = IfNotAnyOrNever<T, {
|
|
67
|
+
ifNot: _IsLiteral<CollapseLiterals<UnwrapBrand<T>>>;
|
|
68
|
+
ifAny: false;
|
|
69
|
+
ifNever: false;
|
|
70
|
+
}>;
|
|
71
|
+
|
|
72
|
+
type _IsLiteral<T> =
|
|
73
|
+
| (Extract<T, boolean> extends infer Bools
|
|
74
|
+
// We can't instantiate `IsBooleanLiteral` with `never`,
|
|
75
|
+
// because that will add an extraneous `false` to the result if there are no booleans.
|
|
76
|
+
? IsNever<Bools> extends true
|
|
77
|
+
? never
|
|
78
|
+
: IsBooleanLiteral<Bools>
|
|
79
|
+
: never)
|
|
80
|
+
| (IsLiteralNonBools<Exclude<T, boolean>>);
|
|
81
|
+
|
|
82
|
+
type IsLiteralNonBools<T> =
|
|
83
|
+
T extends number | bigint
|
|
84
|
+
? IsNumericLiteral<T>
|
|
85
|
+
: T extends string
|
|
86
|
+
? IsStringLiteral<T>
|
|
87
|
+
: T extends symbol
|
|
88
|
+
? IsSymbolLiteral<T>
|
|
89
|
+
: false;
|
|
314
90
|
|
|
315
91
|
export {};
|