@depup/type-fest 5.5.0-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 +1 -1
- package/index.d.ts +16 -8
- package/package.json +8 -6
- package/readme.md +85 -61
- package/source/absolute.d.ts +52 -0
- package/source/all-extend.d.ts +6 -4
- package/source/all-union-fields.d.ts +18 -18
- package/source/and.d.ts +1 -1
- package/source/array-reverse.d.ts +4 -3
- package/source/array-splice.d.ts +24 -24
- 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/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 +11 -11
- 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.d.ts +3 -2
- 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 -8
- 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 +2 -2
- package/source/internal/type.d.ts +16 -10
- package/source/is-boolean-literal.d.ts +39 -0
- 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 +1 -1
- 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/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 -22
- package/source/or.d.ts +1 -1
- 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 +2 -0
- 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 +1 -1
- package/source/set-optional.d.ts +5 -5
- package/source/set-readonly.d.ts +3 -3
- package/source/set-required-deep.d.ts +3 -2
- package/source/set-required.d.ts +3 -3
- package/source/shared-union-fields-deep.d.ts +4 -3
- 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 +6 -4
- package/source/split-on-rest-element.d.ts +6 -4
- package/source/split.d.ts +1 -1
- 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 +3 -5
- 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-to-intersection.d.ts +1 -1
- package/source/union-to-tuple.d.ts +8 -4
- package/source/unwrap-required.d.ts +37 -0
- package/source/words.d.ts +30 -4
- package/source/writable.d.ts +14 -14
- package/source/xor.d.ts +1 -1
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 {};
|
|
@@ -0,0 +1,50 @@
|
|
|
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 `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
import type {IsNumericLiteral} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
type A = IsNumericLiteral<0>;
|
|
12
|
+
//=> true
|
|
13
|
+
|
|
14
|
+
type B = IsNumericLiteral<number>;
|
|
15
|
+
//=> false
|
|
16
|
+
|
|
17
|
+
type C = IsNumericLiteral<100n>;
|
|
18
|
+
//=> true
|
|
19
|
+
|
|
20
|
+
type D = IsNumericLiteral<bigint>;
|
|
21
|
+
//=> false
|
|
22
|
+
|
|
23
|
+
type E = IsNumericLiteral<1 | 2 | 10n | 20n>;
|
|
24
|
+
//=> true
|
|
25
|
+
|
|
26
|
+
type F = IsNumericLiteral<number | bigint>;
|
|
27
|
+
//=> false
|
|
28
|
+
|
|
29
|
+
type G = IsNumericLiteral<1 | bigint>;
|
|
30
|
+
//=> boolean
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
@category Type Guard
|
|
34
|
+
@category Utilities
|
|
35
|
+
*/
|
|
36
|
+
export type IsNumericLiteral<T> = IfNotAnyOrNever<T, {
|
|
37
|
+
ifNot: _IsNumericLiteral<CollapseLiterals<UnwrapBrand<T>>>;
|
|
38
|
+
ifAny: false;
|
|
39
|
+
ifNever: false;
|
|
40
|
+
}>;
|
|
41
|
+
|
|
42
|
+
type _IsNumericLiteral<T> = T extends number | bigint
|
|
43
|
+
? number extends T
|
|
44
|
+
? false
|
|
45
|
+
: bigint extends T
|
|
46
|
+
? false
|
|
47
|
+
: true
|
|
48
|
+
: false;
|
|
49
|
+
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
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 `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
6
|
+
|
|
7
|
+
The implementation of this type is inspired by the trick mentioned in this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
|
|
8
|
+
|
|
9
|
+
@example
|
|
10
|
+
```
|
|
11
|
+
import type {IsStringLiteral} from 'type-fest';
|
|
12
|
+
|
|
13
|
+
type A = IsStringLiteral<'foo'>;
|
|
14
|
+
//=> true
|
|
15
|
+
|
|
16
|
+
type B = IsStringLiteral<string>;
|
|
17
|
+
//=> false
|
|
18
|
+
|
|
19
|
+
// String types with infinite set of possible values return `false`
|
|
20
|
+
type C = IsStringLiteral<`on${string}`>;
|
|
21
|
+
//=> false
|
|
22
|
+
|
|
23
|
+
type D = IsStringLiteral<Uppercase<string>>;
|
|
24
|
+
//=> false
|
|
25
|
+
|
|
26
|
+
type E = IsStringLiteral<'foo' | 'bar' | 'baz'>;
|
|
27
|
+
//=> true
|
|
28
|
+
|
|
29
|
+
type F = IsStringLiteral<'sm' | 'md' | 'lg' | `${number}px`>;
|
|
30
|
+
//=> boolean
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
@example
|
|
34
|
+
```
|
|
35
|
+
import type {IsStringLiteral} from 'type-fest';
|
|
36
|
+
|
|
37
|
+
type StringLength<S extends string, Counter extends never[] = []> =
|
|
38
|
+
IsStringLiteral<S> extends true
|
|
39
|
+
? S extends `${string}${infer Tail}`
|
|
40
|
+
? StringLength<Tail, [...Counter, never]>
|
|
41
|
+
: Counter['length']
|
|
42
|
+
: number; // return `number` for non-literal string types
|
|
43
|
+
|
|
44
|
+
type L1 = StringLength<'foobar'>;
|
|
45
|
+
//=> 6
|
|
46
|
+
|
|
47
|
+
type L2 = StringLength<Lowercase<string>>;
|
|
48
|
+
//=> number
|
|
49
|
+
|
|
50
|
+
type L3 = StringLength<`${number}`>;
|
|
51
|
+
//=> number
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
@category Type Guard
|
|
55
|
+
@category Utilities
|
|
56
|
+
*/
|
|
57
|
+
export type IsStringLiteral<S> = IfNotAnyOrNever<S, {
|
|
58
|
+
ifNot: _IsStringLiteral<CollapseLiterals<UnwrapBrand<S>>>;
|
|
59
|
+
ifAny: false;
|
|
60
|
+
ifNever: false;
|
|
61
|
+
}>;
|
|
62
|
+
|
|
63
|
+
type _IsStringLiteral<S> =
|
|
64
|
+
// If `S` is an infinite string type (e.g., `on${string}`), `Record<S, never>` produces an index signature,
|
|
65
|
+
// and since `{}` extends index signatures, the result becomes `false`.
|
|
66
|
+
S extends string
|
|
67
|
+
? {} extends Record<S, never>
|
|
68
|
+
? false
|
|
69
|
+
: true
|
|
70
|
+
: false;
|
|
71
|
+
|
|
72
|
+
export {};
|
|
@@ -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 `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```
|
|
9
|
+
import type {IsSymbolLiteral} from 'type-fest';
|
|
10
|
+
|
|
11
|
+
declare const symbolLiteral1: unique symbol;
|
|
12
|
+
declare const symbolLiteral2: unique symbol;
|
|
13
|
+
|
|
14
|
+
type A = IsSymbolLiteral<typeof symbolLiteral1>;
|
|
15
|
+
//=> true
|
|
16
|
+
|
|
17
|
+
type B = IsSymbolLiteral<symbol>;
|
|
18
|
+
//=> false
|
|
19
|
+
|
|
20
|
+
type C = IsSymbolLiteral<typeof symbolLiteral1 | typeof symbolLiteral2>;
|
|
21
|
+
//=> true
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
@category Type Guard
|
|
25
|
+
@category Utilities
|
|
26
|
+
*/
|
|
27
|
+
export type IsSymbolLiteral<T> = IfNotAnyOrNever<T, {
|
|
28
|
+
ifNot: _IsSymbolLiteral<CollapseLiterals<UnwrapBrand<T>>>;
|
|
29
|
+
ifAny: false;
|
|
30
|
+
ifNever: false;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
type _IsSymbolLiteral<T> = T extends symbol
|
|
34
|
+
? symbol extends T
|
|
35
|
+
? false
|
|
36
|
+
: true
|
|
37
|
+
: false;
|
|
38
|
+
|
|
39
|
+
export {};
|
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
|
@@ -25,15 +25,11 @@ type JsonifyList<T extends UnknownArray> = T extends readonly []
|
|
|
25
25
|
? JsonValue[]
|
|
26
26
|
: Array<T[number] extends NotJsonable ? null : Jsonify<UndefinedToNull<T[number]>>>;
|
|
27
27
|
|
|
28
|
-
type FilterJsonableKeys<T extends object> = {
|
|
29
|
-
[Key in keyof T]: T[Key] extends NotJsonable ? never : Key;
|
|
30
|
-
}[keyof T];
|
|
31
|
-
|
|
32
28
|
/**
|
|
33
29
|
JSON serialize objects (not including arrays) and classes.
|
|
34
30
|
*/
|
|
35
31
|
type JsonifyObject<T extends object> = {
|
|
36
|
-
[Key in keyof
|
|
32
|
+
[Key in keyof T as T[Key] extends NotJsonable ? never : Key]: Jsonify<T[Key]>;
|
|
37
33
|
};
|
|
38
34
|
|
|
39
35
|
/**
|
|
@@ -98,13 +94,13 @@ export type Jsonify<T> = IsAny<T> extends true
|
|
|
98
94
|
? null
|
|
99
95
|
: T extends JsonPrimitive
|
|
100
96
|
? T
|
|
101
|
-
|
|
102
|
-
T extends {toJSON(): infer J}
|
|
97
|
+
// Any object with toJSON is special case
|
|
98
|
+
: T extends {toJSON(): infer J}
|
|
103
99
|
? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
|
|
104
100
|
? J // Then T is Jsonable and its Jsonable value is J
|
|
105
101
|
: Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
|
|
106
|
-
|
|
107
|
-
T extends Number
|
|
102
|
+
// Instanced primitives are objects
|
|
103
|
+
: T extends Number
|
|
108
104
|
? number
|
|
109
105
|
: T extends String
|
|
110
106
|
? 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 {};
|