@visulima/object 1.0.10 β 1.0.11
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/CHANGELOG.md +15 -0
- package/dist/index.d.cts +7 -2456
- package/dist/index.d.mts +7 -2456
- package/dist/index.d.ts +7 -2456
- package/dist/omit.d.cts +20 -0
- package/dist/omit.d.mts +20 -0
- package/dist/omit.d.ts +20 -0
- package/dist/pick.d.cts +20 -0
- package/dist/pick.d.mts +20 -0
- package/dist/pick.d.ts +20 -0
- package/dist/utils/paths-are-equal.d.cts +9 -0
- package/dist/utils/paths-are-equal.d.mts +9 -0
- package/dist/utils/paths-are-equal.d.ts +9 -0
- package/dist/utils/recursive-omit.d.cts +3 -0
- package/dist/utils/recursive-omit.d.mts +3 -0
- package/dist/utils/recursive-omit.d.ts +3 -0
- package/dist/utils/recursive-pick.d.cts +3 -0
- package/dist/utils/recursive-pick.d.mts +3 -0
- package/dist/utils/recursive-pick.d.ts +3 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,2456 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
| undefined
|
|
9
|
-
| string
|
|
10
|
-
| number
|
|
11
|
-
| boolean
|
|
12
|
-
| symbol
|
|
13
|
-
| bigint;
|
|
14
|
-
|
|
15
|
-
declare global {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
|
|
17
|
-
interface SymbolConstructor {
|
|
18
|
-
readonly observable: symbol;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
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).
|
|
24
|
-
|
|
25
|
-
Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
|
|
26
|
-
|
|
27
|
-
@example
|
|
28
|
-
```
|
|
29
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
30
|
-
|
|
31
|
-
type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
|
|
32
|
-
|
|
33
|
-
type Intersection = UnionToIntersection<Union>;
|
|
34
|
-
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
A more applicable example which could make its way into your library code follows.
|
|
38
|
-
|
|
39
|
-
@example
|
|
40
|
-
```
|
|
41
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
42
|
-
|
|
43
|
-
class CommandOne {
|
|
44
|
-
commands: {
|
|
45
|
-
a1: () => undefined,
|
|
46
|
-
b1: () => undefined,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class CommandTwo {
|
|
51
|
-
commands: {
|
|
52
|
-
a2: (argA: string) => undefined,
|
|
53
|
-
b2: (argB: string) => undefined,
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
58
|
-
type Union = typeof union;
|
|
59
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
60
|
-
|
|
61
|
-
type Intersection = UnionToIntersection<Union>;
|
|
62
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
@category Type
|
|
66
|
-
*/
|
|
67
|
-
type UnionToIntersection<Union> = (
|
|
68
|
-
// `extends unknown` is always going to be the case and is used to convert the
|
|
69
|
-
// `Union` into a [distributive conditional
|
|
70
|
-
// type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
|
|
71
|
-
Union extends unknown
|
|
72
|
-
// The union type is used as the only argument to a function since the union
|
|
73
|
-
// of function arguments is an intersection.
|
|
74
|
-
? (distributedUnion: Union) => void
|
|
75
|
-
// This won't happen.
|
|
76
|
-
: never
|
|
77
|
-
// Infer the `Intersection` type since TypeScript represents the positional
|
|
78
|
-
// arguments of unions of functions as an intersection of the union.
|
|
79
|
-
) extends ((mergedIntersection: infer Intersection) => void)
|
|
80
|
-
// The `& Union` is to allow indexing by the resulting type
|
|
81
|
-
? Intersection & Union
|
|
82
|
-
: never;
|
|
83
|
-
|
|
84
|
-
declare const emptyObjectSymbol: unique symbol;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
Represents a strictly empty plain object, the `{}` value.
|
|
88
|
-
|
|
89
|
-
When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)).
|
|
90
|
-
|
|
91
|
-
@example
|
|
92
|
-
```
|
|
93
|
-
import type {EmptyObject} from 'type-fest';
|
|
94
|
-
|
|
95
|
-
// The following illustrates the problem with `{}`.
|
|
96
|
-
const foo1: {} = {}; // Pass
|
|
97
|
-
const foo2: {} = []; // Pass
|
|
98
|
-
const foo3: {} = 42; // Pass
|
|
99
|
-
const foo4: {} = {a: 1}; // Pass
|
|
100
|
-
|
|
101
|
-
// With `EmptyObject` only the first case is valid.
|
|
102
|
-
const bar1: EmptyObject = {}; // Pass
|
|
103
|
-
const bar2: EmptyObject = 42; // Fail
|
|
104
|
-
const bar3: EmptyObject = []; // Fail
|
|
105
|
-
const bar4: EmptyObject = {a: 1}; // Fail
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<never, never>` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395 #395}.
|
|
109
|
-
|
|
110
|
-
@category Object
|
|
111
|
-
*/
|
|
112
|
-
type EmptyObject = {[emptyObjectSymbol]?: never};
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
Returns a boolean for whether the two given types are equal.
|
|
116
|
-
|
|
117
|
-
@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
|
|
118
|
-
@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
|
|
119
|
-
|
|
120
|
-
Use-cases:
|
|
121
|
-
- If you want to make a conditional branch based on the result of a comparison of two types.
|
|
122
|
-
|
|
123
|
-
@example
|
|
124
|
-
```
|
|
125
|
-
import type {IsEqual} from 'type-fest';
|
|
126
|
-
|
|
127
|
-
// This type returns a boolean for whether the given array includes the given item.
|
|
128
|
-
// `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.
|
|
129
|
-
type Includes<Value extends readonly any[], Item> =
|
|
130
|
-
Value extends readonly [Value[0], ...infer rest]
|
|
131
|
-
? IsEqual<Value[0], Item> extends true
|
|
132
|
-
? true
|
|
133
|
-
: Includes<rest, Item>
|
|
134
|
-
: false;
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
@category Type Guard
|
|
138
|
-
@category Utilities
|
|
139
|
-
*/
|
|
140
|
-
type IsEqual<A, B> =
|
|
141
|
-
(<G>() => G extends A & G | G ? 1 : 2) extends
|
|
142
|
-
(<G>() => G extends B & G | G ? 1 : 2)
|
|
143
|
-
? true
|
|
144
|
-
: false;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
Represents an array with `unknown` value.
|
|
148
|
-
|
|
149
|
-
Use case: You want a type that all arrays can be assigned to, but you don't care about the value.
|
|
150
|
-
|
|
151
|
-
@example
|
|
152
|
-
```
|
|
153
|
-
import type {UnknownArray} from 'type-fest';
|
|
154
|
-
|
|
155
|
-
type IsArray<T> = T extends UnknownArray ? true : false;
|
|
156
|
-
|
|
157
|
-
type A = IsArray<['foo']>;
|
|
158
|
-
//=> true
|
|
159
|
-
|
|
160
|
-
type B = IsArray<readonly number[]>;
|
|
161
|
-
//=> true
|
|
162
|
-
|
|
163
|
-
type C = IsArray<string>;
|
|
164
|
-
//=> false
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
@category Type
|
|
168
|
-
@category Array
|
|
169
|
-
*/
|
|
170
|
-
type UnknownArray = readonly unknown[];
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
|
174
|
-
|
|
175
|
-
@example
|
|
176
|
-
```
|
|
177
|
-
import type {Simplify} from 'type-fest';
|
|
178
|
-
|
|
179
|
-
type PositionProps = {
|
|
180
|
-
top: number;
|
|
181
|
-
left: number;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
type SizeProps = {
|
|
185
|
-
width: number;
|
|
186
|
-
height: number;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// In your editor, hovering over `Props` will show a flattened object with all the properties.
|
|
190
|
-
type Props = Simplify<PositionProps & SizeProps>;
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
|
|
194
|
-
|
|
195
|
-
If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
|
|
196
|
-
|
|
197
|
-
@example
|
|
198
|
-
```
|
|
199
|
-
import type {Simplify} from 'type-fest';
|
|
200
|
-
|
|
201
|
-
interface SomeInterface {
|
|
202
|
-
foo: number;
|
|
203
|
-
bar?: string;
|
|
204
|
-
baz: number | undefined;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
type SomeType = {
|
|
208
|
-
foo: number;
|
|
209
|
-
bar?: string;
|
|
210
|
-
baz: number | undefined;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const literal = {foo: 123, bar: 'hello', baz: 456};
|
|
214
|
-
const someType: SomeType = literal;
|
|
215
|
-
const someInterface: SomeInterface = literal;
|
|
216
|
-
|
|
217
|
-
function fn(object: Record<string, unknown>): void {}
|
|
218
|
-
|
|
219
|
-
fn(literal); // Good: literal object type is sealed
|
|
220
|
-
fn(someType); // Good: type is sealed
|
|
221
|
-
fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
|
|
222
|
-
fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
@link https://github.com/microsoft/TypeScript/issues/15300
|
|
226
|
-
@see SimplifyDeep
|
|
227
|
-
@category Object
|
|
228
|
-
*/
|
|
229
|
-
type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
Returns a boolean for whether the given type is `never`.
|
|
233
|
-
|
|
234
|
-
@link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
|
|
235
|
-
@link https://stackoverflow.com/a/53984913/10292952
|
|
236
|
-
@link https://www.zhenghao.io/posts/ts-never
|
|
237
|
-
|
|
238
|
-
Useful in type utilities, such as checking if something does not occur.
|
|
239
|
-
|
|
240
|
-
@example
|
|
241
|
-
```
|
|
242
|
-
import type {IsNever, And} from 'type-fest';
|
|
243
|
-
|
|
244
|
-
// https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
|
|
245
|
-
type AreStringsEqual<A extends string, B extends string> =
|
|
246
|
-
And<
|
|
247
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
248
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
249
|
-
>;
|
|
250
|
-
|
|
251
|
-
type EndIfEqual<I extends string, O extends string> =
|
|
252
|
-
AreStringsEqual<I, O> extends true
|
|
253
|
-
? never
|
|
254
|
-
: void;
|
|
255
|
-
|
|
256
|
-
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
257
|
-
if (input === output) {
|
|
258
|
-
process.exit(0);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
endIfEqual('abc', 'abc');
|
|
263
|
-
//=> never
|
|
264
|
-
|
|
265
|
-
endIfEqual('abc', '123');
|
|
266
|
-
//=> void
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
@category Type Guard
|
|
270
|
-
@category Utilities
|
|
271
|
-
*/
|
|
272
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
An if-else-like type that resolves depending on whether the given type is `never`.
|
|
276
|
-
|
|
277
|
-
@see {@link IsNever}
|
|
278
|
-
|
|
279
|
-
@example
|
|
280
|
-
```
|
|
281
|
-
import type {IfNever} from 'type-fest';
|
|
282
|
-
|
|
283
|
-
type ShouldBeTrue = IfNever<never>;
|
|
284
|
-
//=> true
|
|
285
|
-
|
|
286
|
-
type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
|
|
287
|
-
//=> 'bar'
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
@category Type Guard
|
|
291
|
-
@category Utilities
|
|
292
|
-
*/
|
|
293
|
-
type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
|
|
294
|
-
IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
Returns the static, fixed-length portion of the given array, excluding variable-length parts.
|
|
299
|
-
|
|
300
|
-
@example
|
|
301
|
-
```
|
|
302
|
-
type A = [string, number, boolean, ...string[]];
|
|
303
|
-
type B = StaticPartOfArray<A>;
|
|
304
|
-
//=> [string, number, boolean]
|
|
305
|
-
```
|
|
306
|
-
*/
|
|
307
|
-
type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
|
|
308
|
-
T extends unknown
|
|
309
|
-
? number extends T['length'] ?
|
|
310
|
-
T extends readonly [infer U, ...infer V]
|
|
311
|
-
? StaticPartOfArray<V, [...Result, U]>
|
|
312
|
-
: Result
|
|
313
|
-
: T
|
|
314
|
-
: never; // Should never happen
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
Returns the variable, non-fixed-length portion of the given array, excluding static-length parts.
|
|
318
|
-
|
|
319
|
-
@example
|
|
320
|
-
```
|
|
321
|
-
type A = [string, number, boolean, ...string[]];
|
|
322
|
-
type B = VariablePartOfArray<A>;
|
|
323
|
-
//=> string[]
|
|
324
|
-
```
|
|
325
|
-
*/
|
|
326
|
-
type VariablePartOfArray<T extends UnknownArray> =
|
|
327
|
-
T extends unknown
|
|
328
|
-
? T extends readonly [...StaticPartOfArray<T>, ...infer U]
|
|
329
|
-
? U
|
|
330
|
-
: []
|
|
331
|
-
: never; // Should never happen
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
Set the given array to readonly if `IsReadonly` is `true`, otherwise set the given array to normal, then return the result.
|
|
335
|
-
|
|
336
|
-
@example
|
|
337
|
-
```
|
|
338
|
-
type ReadonlyArray = readonly string[];
|
|
339
|
-
type NormalArray = string[];
|
|
340
|
-
|
|
341
|
-
type ReadonlyResult = SetArrayAccess<NormalArray, true>;
|
|
342
|
-
//=> readonly string[]
|
|
343
|
-
|
|
344
|
-
type NormalResult = SetArrayAccess<ReadonlyArray, false>;
|
|
345
|
-
//=> string[]
|
|
346
|
-
```
|
|
347
|
-
*/
|
|
348
|
-
type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
|
|
349
|
-
T extends readonly [...infer U] ?
|
|
350
|
-
IsReadonly extends true
|
|
351
|
-
? readonly [...U]
|
|
352
|
-
: [...U]
|
|
353
|
-
: T;
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
Returns whether the given array `T` is readonly.
|
|
357
|
-
*/
|
|
358
|
-
type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
|
|
359
|
-
|
|
360
|
-
type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
361
|
-
|
|
362
|
-
// Can eventually be replaced with the built-in once this library supports
|
|
363
|
-
// TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
|
|
364
|
-
type NoInfer<T> = T extends infer U ? U : never;
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
Returns a boolean for whether the given type is `any`.
|
|
368
|
-
|
|
369
|
-
@link https://stackoverflow.com/a/49928360/1490091
|
|
370
|
-
|
|
371
|
-
Useful in type utilities, such as disallowing `any`s to be passed to a function.
|
|
372
|
-
|
|
373
|
-
@example
|
|
374
|
-
```
|
|
375
|
-
import type {IsAny} from 'type-fest';
|
|
376
|
-
|
|
377
|
-
const typedObject = {a: 1, b: 2} as const;
|
|
378
|
-
const anyObject: any = {a: 1, b: 2};
|
|
379
|
-
|
|
380
|
-
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
|
|
381
|
-
return obj[key];
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const typedA = get(typedObject, 'a');
|
|
385
|
-
//=> 1
|
|
386
|
-
|
|
387
|
-
const anyA = get(anyObject, 'a');
|
|
388
|
-
//=> any
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
@category Type Guard
|
|
392
|
-
@category Utilities
|
|
393
|
-
*/
|
|
394
|
-
type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
|
|
395
|
-
|
|
396
|
-
type Numeric = number | bigint;
|
|
397
|
-
|
|
398
|
-
type Zero = 0 | 0n;
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
Matches the hidden `Infinity` type.
|
|
402
|
-
|
|
403
|
-
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
|
|
404
|
-
|
|
405
|
-
@see NegativeInfinity
|
|
406
|
-
|
|
407
|
-
@category Numeric
|
|
408
|
-
*/
|
|
409
|
-
// See https://github.com/microsoft/TypeScript/issues/31752
|
|
410
|
-
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
|
|
411
|
-
type PositiveInfinity = 1e999;
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
Matches the hidden `-Infinity` type.
|
|
415
|
-
|
|
416
|
-
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
|
|
417
|
-
|
|
418
|
-
@see PositiveInfinity
|
|
419
|
-
|
|
420
|
-
@category Numeric
|
|
421
|
-
*/
|
|
422
|
-
// See https://github.com/microsoft/TypeScript/issues/31752
|
|
423
|
-
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
|
|
424
|
-
type NegativeInfinity = -1e999;
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
A negative `number`/`bigint` (`-β < x < 0`)
|
|
428
|
-
|
|
429
|
-
Use-case: Validating and documenting parameters.
|
|
430
|
-
|
|
431
|
-
@see NegativeInteger
|
|
432
|
-
@see NonNegative
|
|
433
|
-
|
|
434
|
-
@category Numeric
|
|
435
|
-
*/
|
|
436
|
-
type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never;
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
Returns a boolean for whether the given number is a negative number.
|
|
440
|
-
|
|
441
|
-
@see Negative
|
|
442
|
-
|
|
443
|
-
@example
|
|
444
|
-
```
|
|
445
|
-
import type {IsNegative} from 'type-fest';
|
|
446
|
-
|
|
447
|
-
type ShouldBeFalse = IsNegative<1>;
|
|
448
|
-
type ShouldBeTrue = IsNegative<-1>;
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
@category Numeric
|
|
452
|
-
*/
|
|
453
|
-
type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
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).
|
|
457
|
-
|
|
458
|
-
Useful for:
|
|
459
|
-
- providing strongly-typed string manipulation functions
|
|
460
|
-
- constraining strings to be a string literal
|
|
461
|
-
- type utilities, such as when constructing parsers and ASTs
|
|
462
|
-
|
|
463
|
-
The implementation of this type is inspired by the trick mentioned in this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
|
|
464
|
-
|
|
465
|
-
@example
|
|
466
|
-
```
|
|
467
|
-
import type {IsStringLiteral} from 'type-fest';
|
|
468
|
-
|
|
469
|
-
type CapitalizedString<T extends string> = IsStringLiteral<T> extends true ? Capitalize<T> : string;
|
|
470
|
-
|
|
471
|
-
// https://github.com/yankeeinlondon/native-dash/blob/master/src/capitalize.ts
|
|
472
|
-
function capitalize<T extends Readonly<string>>(input: T): CapitalizedString<T> {
|
|
473
|
-
return (input.slice(0, 1).toUpperCase() + input.slice(1)) as CapitalizedString<T>;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const output = capitalize('hello, world!');
|
|
477
|
-
//=> 'Hello, world!'
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
@example
|
|
481
|
-
```
|
|
482
|
-
// String types with infinite set of possible values return `false`.
|
|
483
|
-
|
|
484
|
-
import type {IsStringLiteral} from 'type-fest';
|
|
485
|
-
|
|
486
|
-
type AllUppercaseStrings = IsStringLiteral<Uppercase<string>>;
|
|
487
|
-
//=> false
|
|
488
|
-
|
|
489
|
-
type StringsStartingWithOn = IsStringLiteral<`on${string}`>;
|
|
490
|
-
//=> false
|
|
491
|
-
|
|
492
|
-
// This behaviour is particularly useful in string manipulation utilities, as infinite string types often require separate handling.
|
|
493
|
-
|
|
494
|
-
type Length<S extends string, Counter extends never[] = []> =
|
|
495
|
-
IsStringLiteral<S> extends false
|
|
496
|
-
? number // return `number` for infinite string types
|
|
497
|
-
: S extends `${string}${infer Tail}`
|
|
498
|
-
? Length<Tail, [...Counter, never]>
|
|
499
|
-
: Counter['length'];
|
|
500
|
-
|
|
501
|
-
type L1 = Length<Lowercase<string>>;
|
|
502
|
-
//=> number
|
|
503
|
-
|
|
504
|
-
type L2 = Length<`${number}`>;
|
|
505
|
-
//=> number
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
@category Type Guard
|
|
509
|
-
@category Utilities
|
|
510
|
-
*/
|
|
511
|
-
type IsStringLiteral<T> = IfNever<T, false,
|
|
512
|
-
// If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
|
|
513
|
-
// and since `{}` extends index signatures, the result becomes `false`.
|
|
514
|
-
T extends string
|
|
515
|
-
? {} extends Record<T, never>
|
|
516
|
-
? false
|
|
517
|
-
: true
|
|
518
|
-
: false>;
|
|
519
|
-
|
|
520
|
-
/**
|
|
521
|
-
Returns a boolean for whether two given types are both true.
|
|
522
|
-
|
|
523
|
-
Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
|
|
524
|
-
|
|
525
|
-
@example
|
|
526
|
-
```
|
|
527
|
-
import type {And} from 'type-fest';
|
|
528
|
-
|
|
529
|
-
And<true, true>;
|
|
530
|
-
//=> true
|
|
531
|
-
|
|
532
|
-
And<true, false>;
|
|
533
|
-
//=> false
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
@see {@link Or}
|
|
537
|
-
*/
|
|
538
|
-
type And<A extends boolean, B extends boolean> = [A, B][number] extends true
|
|
539
|
-
? true
|
|
540
|
-
: true extends [IsEqual<A, false>, IsEqual<B, false>][number]
|
|
541
|
-
? false
|
|
542
|
-
: never;
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
Returns a boolean for whether either of two given types are true.
|
|
546
|
-
|
|
547
|
-
Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
|
|
548
|
-
|
|
549
|
-
@example
|
|
550
|
-
```
|
|
551
|
-
import type {Or} from 'type-fest';
|
|
552
|
-
|
|
553
|
-
Or<true, false>;
|
|
554
|
-
//=> true
|
|
555
|
-
|
|
556
|
-
Or<false, false>;
|
|
557
|
-
//=> false
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
@see {@link And}
|
|
561
|
-
*/
|
|
562
|
-
type Or<A extends boolean, B extends boolean> = [A, B][number] extends false
|
|
563
|
-
? false
|
|
564
|
-
: true extends [IsEqual<A, true>, IsEqual<B, true>][number]
|
|
565
|
-
? true
|
|
566
|
-
: never;
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
Returns a boolean for whether a given number is greater than another number.
|
|
570
|
-
|
|
571
|
-
@example
|
|
572
|
-
```
|
|
573
|
-
import type {GreaterThan} from 'type-fest';
|
|
574
|
-
|
|
575
|
-
GreaterThan<1, -5>;
|
|
576
|
-
//=> true
|
|
577
|
-
|
|
578
|
-
GreaterThan<1, 1>;
|
|
579
|
-
//=> false
|
|
580
|
-
|
|
581
|
-
GreaterThan<1, 5>;
|
|
582
|
-
//=> false
|
|
583
|
-
```
|
|
584
|
-
*/
|
|
585
|
-
type GreaterThan<A extends number, B extends number> = number extends A | B
|
|
586
|
-
? never
|
|
587
|
-
: [
|
|
588
|
-
IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
|
|
589
|
-
IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
|
|
590
|
-
] extends infer R extends [boolean, boolean, boolean, boolean]
|
|
591
|
-
? Or<
|
|
592
|
-
And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
|
|
593
|
-
And<IsEqual<R[3], true>, IsEqual<R[1], false>>
|
|
594
|
-
> extends true
|
|
595
|
-
? true
|
|
596
|
-
: Or<
|
|
597
|
-
And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
|
|
598
|
-
And<IsEqual<R[2], true>, IsEqual<R[0], false>>
|
|
599
|
-
> extends true
|
|
600
|
-
? false
|
|
601
|
-
: true extends R[number]
|
|
602
|
-
? false
|
|
603
|
-
: [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
|
|
604
|
-
? [true, false] extends R
|
|
605
|
-
? false
|
|
606
|
-
: [false, true] extends R
|
|
607
|
-
? true
|
|
608
|
-
: [false, false] extends R
|
|
609
|
-
? PositiveNumericStringGt<`${A}`, `${B}`>
|
|
610
|
-
: PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`>
|
|
611
|
-
: never
|
|
612
|
-
: never;
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
Returns a boolean for whether a given number is greater than or equal to another number.
|
|
616
|
-
|
|
617
|
-
@example
|
|
618
|
-
```
|
|
619
|
-
import type {GreaterThanOrEqual} from 'type-fest';
|
|
620
|
-
|
|
621
|
-
GreaterThanOrEqual<1, -5>;
|
|
622
|
-
//=> true
|
|
623
|
-
|
|
624
|
-
GreaterThanOrEqual<1, 1>;
|
|
625
|
-
//=> true
|
|
626
|
-
|
|
627
|
-
GreaterThanOrEqual<1, 5>;
|
|
628
|
-
//=> false
|
|
629
|
-
```
|
|
630
|
-
*/
|
|
631
|
-
type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B
|
|
632
|
-
? never
|
|
633
|
-
: A extends B ? true : GreaterThan<A, B>;
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
Returns a boolean for whether a given number is less than another number.
|
|
637
|
-
|
|
638
|
-
@example
|
|
639
|
-
```
|
|
640
|
-
import type {LessThan} from 'type-fest';
|
|
641
|
-
|
|
642
|
-
LessThan<1, -5>;
|
|
643
|
-
//=> false
|
|
644
|
-
|
|
645
|
-
LessThan<1, 1>;
|
|
646
|
-
//=> false
|
|
647
|
-
|
|
648
|
-
LessThan<1, 5>;
|
|
649
|
-
//=> true
|
|
650
|
-
```
|
|
651
|
-
*/
|
|
652
|
-
type LessThan<A extends number, B extends number> = number extends A | B
|
|
653
|
-
? never
|
|
654
|
-
: GreaterThanOrEqual<A, B> extends true ? false : true;
|
|
655
|
-
|
|
656
|
-
// Should never happen
|
|
657
|
-
|
|
658
|
-
/**
|
|
659
|
-
Create a tuple type of the given length `<L>` and fill it with the given type `<Fill>`.
|
|
660
|
-
|
|
661
|
-
If `<Fill>` is not provided, it will default to `unknown`.
|
|
662
|
-
|
|
663
|
-
@link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
|
|
664
|
-
*/
|
|
665
|
-
type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L
|
|
666
|
-
? Fill[]
|
|
667
|
-
: L extends T['length']
|
|
668
|
-
? T
|
|
669
|
-
: BuildTuple<L, Fill, [...T, Fill]>;
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
Return a string representation of the given string or number.
|
|
673
|
-
|
|
674
|
-
Note: This type is not the return type of the `.toString()` function.
|
|
675
|
-
*/
|
|
676
|
-
type ToString<T> = T extends string | number ? `${T}` : never;
|
|
677
|
-
|
|
678
|
-
/**
|
|
679
|
-
Converts a numeric string to a number.
|
|
680
|
-
|
|
681
|
-
@example
|
|
682
|
-
```
|
|
683
|
-
type PositiveInt = StringToNumber<'1234'>;
|
|
684
|
-
//=> 1234
|
|
685
|
-
|
|
686
|
-
type NegativeInt = StringToNumber<'-1234'>;
|
|
687
|
-
//=> -1234
|
|
688
|
-
|
|
689
|
-
type PositiveFloat = StringToNumber<'1234.56'>;
|
|
690
|
-
//=> 1234.56
|
|
691
|
-
|
|
692
|
-
type NegativeFloat = StringToNumber<'-1234.56'>;
|
|
693
|
-
//=> -1234.56
|
|
694
|
-
|
|
695
|
-
type PositiveInfinity = StringToNumber<'Infinity'>;
|
|
696
|
-
//=> Infinity
|
|
697
|
-
|
|
698
|
-
type NegativeInfinity = StringToNumber<'-Infinity'>;
|
|
699
|
-
//=> -Infinity
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
@category String
|
|
703
|
-
@category Numeric
|
|
704
|
-
@category Template literal
|
|
705
|
-
*/
|
|
706
|
-
type StringToNumber<S extends string> = S extends `${infer N extends number}`
|
|
707
|
-
? N
|
|
708
|
-
: S extends 'Infinity'
|
|
709
|
-
? PositiveInfinity
|
|
710
|
-
: S extends '-Infinity'
|
|
711
|
-
? NegativeInfinity
|
|
712
|
-
: never;
|
|
713
|
-
|
|
714
|
-
/**
|
|
715
|
-
Returns an array of the characters of the string.
|
|
716
|
-
|
|
717
|
-
@example
|
|
718
|
-
```
|
|
719
|
-
StringToArray<'abcde'>;
|
|
720
|
-
//=> ['a', 'b', 'c', 'd', 'e']
|
|
721
|
-
|
|
722
|
-
StringToArray<string>;
|
|
723
|
-
//=> never
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
@category String
|
|
727
|
-
*/
|
|
728
|
-
type StringToArray<S extends string, Result extends string[] = []> = string extends S
|
|
729
|
-
? never
|
|
730
|
-
: S extends `${infer F}${infer R}`
|
|
731
|
-
? StringToArray<R, [...Result, F]>
|
|
732
|
-
: Result;
|
|
733
|
-
|
|
734
|
-
/**
|
|
735
|
-
Returns the length of the given string.
|
|
736
|
-
|
|
737
|
-
@example
|
|
738
|
-
```
|
|
739
|
-
StringLength<'abcde'>;
|
|
740
|
-
//=> 5
|
|
741
|
-
|
|
742
|
-
StringLength<string>;
|
|
743
|
-
//=> never
|
|
744
|
-
```
|
|
745
|
-
|
|
746
|
-
@category String
|
|
747
|
-
@category Template literal
|
|
748
|
-
*/
|
|
749
|
-
type StringLength<S extends string> = string extends S
|
|
750
|
-
? never
|
|
751
|
-
: StringToArray<S>['length'];
|
|
752
|
-
|
|
753
|
-
/**
|
|
754
|
-
Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both numeric strings and have the same length.
|
|
755
|
-
|
|
756
|
-
@example
|
|
757
|
-
```
|
|
758
|
-
SameLengthPositiveNumericStringGt<'50', '10'>;
|
|
759
|
-
//=> true
|
|
760
|
-
|
|
761
|
-
SameLengthPositiveNumericStringGt<'10', '10'>;
|
|
762
|
-
//=> false
|
|
763
|
-
```
|
|
764
|
-
*/
|
|
765
|
-
type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}`
|
|
766
|
-
? B extends `${infer FirstB}${infer RestB}`
|
|
767
|
-
? FirstA extends FirstB
|
|
768
|
-
? SameLengthPositiveNumericStringGt<RestA, RestB>
|
|
769
|
-
: PositiveNumericCharacterGt<FirstA, FirstB>
|
|
770
|
-
: never
|
|
771
|
-
: false;
|
|
772
|
-
|
|
773
|
-
type NumericString = '0123456789';
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
|
|
777
|
-
|
|
778
|
-
@example
|
|
779
|
-
```
|
|
780
|
-
PositiveNumericStringGt<'500', '1'>;
|
|
781
|
-
//=> true
|
|
782
|
-
|
|
783
|
-
PositiveNumericStringGt<'1', '1'>;
|
|
784
|
-
//=> false
|
|
785
|
-
|
|
786
|
-
PositiveNumericStringGt<'1', '500'>;
|
|
787
|
-
//=> false
|
|
788
|
-
```
|
|
789
|
-
*/
|
|
790
|
-
type PositiveNumericStringGt<A extends string, B extends string> = A extends B
|
|
791
|
-
? false
|
|
792
|
-
: [BuildTuple<StringLength<A>, 0>, BuildTuple<StringLength<B>, 0>] extends infer R extends [readonly unknown[], readonly unknown[]]
|
|
793
|
-
? R[0] extends [...R[1], ...infer Remain extends readonly unknown[]]
|
|
794
|
-
? 0 extends Remain['length']
|
|
795
|
-
? SameLengthPositiveNumericStringGt<A, B>
|
|
796
|
-
: true
|
|
797
|
-
: false
|
|
798
|
-
: never;
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both positive numeric characters.
|
|
802
|
-
|
|
803
|
-
@example
|
|
804
|
-
```
|
|
805
|
-
PositiveNumericCharacterGt<'5', '1'>;
|
|
806
|
-
//=> true
|
|
807
|
-
|
|
808
|
-
PositiveNumericCharacterGt<'1', '1'>;
|
|
809
|
-
//=> false
|
|
810
|
-
```
|
|
811
|
-
*/
|
|
812
|
-
type PositiveNumericCharacterGt<A extends string, B extends string> = NumericString extends `${infer HeadA}${A}${infer TailA}`
|
|
813
|
-
? NumericString extends `${infer HeadB}${B}${infer TailB}`
|
|
814
|
-
? HeadA extends `${HeadB}${infer _}${infer __}`
|
|
815
|
-
? true
|
|
816
|
-
: false
|
|
817
|
-
: never
|
|
818
|
-
: never;
|
|
819
|
-
|
|
820
|
-
/**
|
|
821
|
-
Get the exact version of the given `Key` in the given object `T`.
|
|
822
|
-
|
|
823
|
-
Use-case: You known that a number key (e.g. 10) is in an object, but you don't know how it is defined in the object, as a string or as a number (e.g. 10 or '10'). You can use this type to get the exact version of the key. See the example.
|
|
824
|
-
|
|
825
|
-
@example
|
|
826
|
-
```
|
|
827
|
-
type Object = {
|
|
828
|
-
0: number;
|
|
829
|
-
'1': string;
|
|
830
|
-
};
|
|
831
|
-
|
|
832
|
-
type Key1 = ExactKey<Object, '0'>;
|
|
833
|
-
//=> 0
|
|
834
|
-
type Key2 = ExactKey<Object, 0>;
|
|
835
|
-
//=> 0
|
|
836
|
-
|
|
837
|
-
type Key3 = ExactKey<Object, '1'>;
|
|
838
|
-
//=> '1'
|
|
839
|
-
type Key4 = ExactKey<Object, 1>;
|
|
840
|
-
//=> '1'
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
@category Object
|
|
844
|
-
*/
|
|
845
|
-
type ExactKey<T extends object, Key extends PropertyKey> =
|
|
846
|
-
Key extends keyof T
|
|
847
|
-
? Key
|
|
848
|
-
: ToString<Key> extends keyof T
|
|
849
|
-
? ToString<Key>
|
|
850
|
-
: Key extends `${infer NumberKey extends number}`
|
|
851
|
-
? NumberKey extends keyof T
|
|
852
|
-
? NumberKey
|
|
853
|
-
: never
|
|
854
|
-
: never;
|
|
855
|
-
|
|
856
|
-
/**
|
|
857
|
-
Returns the absolute value of a given value.
|
|
858
|
-
|
|
859
|
-
@example
|
|
860
|
-
```
|
|
861
|
-
NumberAbsolute<-1>;
|
|
862
|
-
//=> 1
|
|
863
|
-
|
|
864
|
-
NumberAbsolute<1>;
|
|
865
|
-
//=> 1
|
|
866
|
-
|
|
867
|
-
NumberAbsolute<NegativeInfinity>
|
|
868
|
-
//=> PositiveInfinity
|
|
869
|
-
```
|
|
870
|
-
*/
|
|
871
|
-
type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
|
|
872
|
-
|
|
873
|
-
/**
|
|
874
|
-
Check whether the given type is a number or a number string.
|
|
875
|
-
|
|
876
|
-
Supports floating-point as a string.
|
|
877
|
-
|
|
878
|
-
@example
|
|
879
|
-
```
|
|
880
|
-
type A = IsNumberLike<'1'>;
|
|
881
|
-
//=> true
|
|
882
|
-
|
|
883
|
-
type B = IsNumberLike<'-1.1'>;
|
|
884
|
-
//=> true
|
|
885
|
-
|
|
886
|
-
type C = IsNumberLike<1>;
|
|
887
|
-
//=> true
|
|
888
|
-
|
|
889
|
-
type D = IsNumberLike<'a'>;
|
|
890
|
-
//=> false
|
|
891
|
-
*/
|
|
892
|
-
type IsNumberLike<N> =
|
|
893
|
-
N extends number ? true
|
|
894
|
-
: N extends `${number}`
|
|
895
|
-
? true
|
|
896
|
-
: N extends `${number}.${number}`
|
|
897
|
-
? true
|
|
898
|
-
: false;
|
|
899
|
-
|
|
900
|
-
/**
|
|
901
|
-
Returns the number with reversed sign.
|
|
902
|
-
|
|
903
|
-
@example
|
|
904
|
-
```
|
|
905
|
-
ReverseSign<-1>;
|
|
906
|
-
//=> 1
|
|
907
|
-
|
|
908
|
-
ReverseSign<1>;
|
|
909
|
-
//=> -1
|
|
910
|
-
|
|
911
|
-
ReverseSign<NegativeInfinity>
|
|
912
|
-
//=> PositiveInfinity
|
|
913
|
-
|
|
914
|
-
ReverseSign<PositiveInfinity>
|
|
915
|
-
//=> NegativeInfinity
|
|
916
|
-
```
|
|
917
|
-
*/
|
|
918
|
-
type ReverseSign<N extends number> =
|
|
919
|
-
// Handle edge cases
|
|
920
|
-
N extends 0 ? 0 : N extends PositiveInfinity ? NegativeInfinity : N extends NegativeInfinity ? PositiveInfinity :
|
|
921
|
-
// Handle negative numbers
|
|
922
|
-
`${N}` extends `-${infer P extends number}` ? P
|
|
923
|
-
// Handle positive numbers
|
|
924
|
-
: `-${N}` extends `${infer R extends number}` ? R : never;
|
|
925
|
-
|
|
926
|
-
/**
|
|
927
|
-
Matches any primitive, `void`, `Date`, or `RegExp` value.
|
|
928
|
-
*/
|
|
929
|
-
type BuiltIns = Primitive | void | Date | RegExp;
|
|
930
|
-
|
|
931
|
-
/**
|
|
932
|
-
Matches non-recursive types.
|
|
933
|
-
*/
|
|
934
|
-
type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
Returns a boolean for whether A is false.
|
|
938
|
-
|
|
939
|
-
@example
|
|
940
|
-
```
|
|
941
|
-
Not<true>;
|
|
942
|
-
//=> false
|
|
943
|
-
|
|
944
|
-
Not<false>;
|
|
945
|
-
//=> true
|
|
946
|
-
```
|
|
947
|
-
*/
|
|
948
|
-
type Not<A extends boolean> = A extends true
|
|
949
|
-
? false
|
|
950
|
-
: A extends false
|
|
951
|
-
? true
|
|
952
|
-
: never;
|
|
953
|
-
|
|
954
|
-
/**
|
|
955
|
-
Create an object type with the given key `<Key>` and value `<Value>`.
|
|
956
|
-
|
|
957
|
-
It will copy the prefix and optional status of the same key from the given object `CopiedFrom` into the result.
|
|
958
|
-
|
|
959
|
-
@example
|
|
960
|
-
```
|
|
961
|
-
type A = BuildObject<'a', string>;
|
|
962
|
-
//=> {a: string}
|
|
963
|
-
|
|
964
|
-
// Copy `readonly` and `?` from the key `a` of `{readonly a?: any}`
|
|
965
|
-
type B = BuildObject<'a', string, {readonly a?: any}>;
|
|
966
|
-
//=> {readonly a?: string}
|
|
967
|
-
```
|
|
968
|
-
*/
|
|
969
|
-
type BuildObject<Key extends PropertyKey, Value, CopiedFrom extends object = {}> =
|
|
970
|
-
Key extends keyof CopiedFrom
|
|
971
|
-
? Pick<{[_ in keyof CopiedFrom]: Value}, Key>
|
|
972
|
-
: Key extends `${infer NumberKey extends number}`
|
|
973
|
-
? NumberKey extends keyof CopiedFrom
|
|
974
|
-
? Pick<{[_ in keyof CopiedFrom]: Value}, NumberKey>
|
|
975
|
-
: {[_ in Key]: Value}
|
|
976
|
-
: {[_ in Key]: Value};
|
|
977
|
-
|
|
978
|
-
/**
|
|
979
|
-
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
980
|
-
|
|
981
|
-
It creates a type-safe way to access the member type of `unknown` type.
|
|
982
|
-
*/
|
|
983
|
-
type ObjectValue<T, K> =
|
|
984
|
-
K extends keyof T
|
|
985
|
-
? T[K]
|
|
986
|
-
: ToString<K> extends keyof T
|
|
987
|
-
? T[ToString<K>]
|
|
988
|
-
: K extends `${infer NumberK extends number}`
|
|
989
|
-
? NumberK extends keyof T
|
|
990
|
-
? T[NumberK]
|
|
991
|
-
: never
|
|
992
|
-
: never;
|
|
993
|
-
|
|
994
|
-
/**
|
|
995
|
-
Deeply simplifies an object type.
|
|
996
|
-
|
|
997
|
-
You can exclude certain types from being simplified by providing them in the second generic `ExcludeType`.
|
|
998
|
-
|
|
999
|
-
Useful to flatten the type output to improve type hints shown in editors.
|
|
1000
|
-
|
|
1001
|
-
@example
|
|
1002
|
-
```
|
|
1003
|
-
import type {SimplifyDeep} from 'type-fest';
|
|
1004
|
-
|
|
1005
|
-
type PositionX = {
|
|
1006
|
-
left: number;
|
|
1007
|
-
right: number;
|
|
1008
|
-
};
|
|
1009
|
-
|
|
1010
|
-
type PositionY = {
|
|
1011
|
-
top: number;
|
|
1012
|
-
bottom: number;
|
|
1013
|
-
};
|
|
1014
|
-
|
|
1015
|
-
type Properties1 = {
|
|
1016
|
-
height: number;
|
|
1017
|
-
position: PositionY;
|
|
1018
|
-
};
|
|
1019
|
-
|
|
1020
|
-
type Properties2 = {
|
|
1021
|
-
width: number;
|
|
1022
|
-
position: PositionX;
|
|
1023
|
-
};
|
|
1024
|
-
|
|
1025
|
-
type Properties = Properties1 & Properties2;
|
|
1026
|
-
// In your editor, hovering over `Props` will show the following:
|
|
1027
|
-
//
|
|
1028
|
-
// type Properties = Properties1 & Properties2;
|
|
1029
|
-
|
|
1030
|
-
type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2>;
|
|
1031
|
-
// But if wrapped in SimplifyDeep, hovering over `SimplifyDeepProperties` will show a flattened object with all the properties:
|
|
1032
|
-
//
|
|
1033
|
-
// SimplifyDeepProperties = {
|
|
1034
|
-
// height: number;
|
|
1035
|
-
// width: number;
|
|
1036
|
-
// position: {
|
|
1037
|
-
// top: number;
|
|
1038
|
-
// bottom: number;
|
|
1039
|
-
// left: number;
|
|
1040
|
-
// right: number;
|
|
1041
|
-
// };
|
|
1042
|
-
// };
|
|
1043
|
-
```
|
|
1044
|
-
|
|
1045
|
-
@example
|
|
1046
|
-
```
|
|
1047
|
-
import type {SimplifyDeep} from 'type-fest';
|
|
1048
|
-
|
|
1049
|
-
// A complex type that you don't want or need to simplify
|
|
1050
|
-
type ComplexType = {
|
|
1051
|
-
a: string;
|
|
1052
|
-
b: 'b';
|
|
1053
|
-
c: number;
|
|
1054
|
-
...
|
|
1055
|
-
};
|
|
1056
|
-
|
|
1057
|
-
type PositionX = {
|
|
1058
|
-
left: number;
|
|
1059
|
-
right: number;
|
|
1060
|
-
};
|
|
1061
|
-
|
|
1062
|
-
type PositionY = {
|
|
1063
|
-
top: number;
|
|
1064
|
-
bottom: number;
|
|
1065
|
-
};
|
|
1066
|
-
|
|
1067
|
-
// You want to simplify all other types
|
|
1068
|
-
type Properties1 = {
|
|
1069
|
-
height: number;
|
|
1070
|
-
position: PositionY;
|
|
1071
|
-
foo: ComplexType;
|
|
1072
|
-
};
|
|
1073
|
-
|
|
1074
|
-
type Properties2 = {
|
|
1075
|
-
width: number;
|
|
1076
|
-
position: PositionX;
|
|
1077
|
-
foo: ComplexType;
|
|
1078
|
-
};
|
|
1079
|
-
|
|
1080
|
-
type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2, ComplexType>;
|
|
1081
|
-
// If wrapped in `SimplifyDeep` and set `ComplexType` to exclude, hovering over `SimplifyDeepProperties` will
|
|
1082
|
-
// show a flattened object with all the properties except `ComplexType`:
|
|
1083
|
-
//
|
|
1084
|
-
// SimplifyDeepProperties = {
|
|
1085
|
-
// height: number;
|
|
1086
|
-
// width: number;
|
|
1087
|
-
// position: {
|
|
1088
|
-
// top: number;
|
|
1089
|
-
// bottom: number;
|
|
1090
|
-
// left: number;
|
|
1091
|
-
// right: number;
|
|
1092
|
-
// };
|
|
1093
|
-
// foo: ComplexType;
|
|
1094
|
-
// };
|
|
1095
|
-
```
|
|
1096
|
-
|
|
1097
|
-
@see Simplify
|
|
1098
|
-
@category Object
|
|
1099
|
-
*/
|
|
1100
|
-
type SimplifyDeep<Type, ExcludeType = never> =
|
|
1101
|
-
ConditionalSimplifyDeep<
|
|
1102
|
-
Type,
|
|
1103
|
-
ExcludeType | NonRecursiveType | Set<unknown> | Map<unknown, unknown>,
|
|
1104
|
-
object
|
|
1105
|
-
>;
|
|
1106
|
-
|
|
1107
|
-
/**
|
|
1108
|
-
Returns the difference between two numbers.
|
|
1109
|
-
|
|
1110
|
-
Note:
|
|
1111
|
-
- A or B can only support `-999` ~ `999`.
|
|
1112
|
-
|
|
1113
|
-
@example
|
|
1114
|
-
```
|
|
1115
|
-
import type {Subtract} from 'type-fest';
|
|
1116
|
-
|
|
1117
|
-
Subtract<333, 222>;
|
|
1118
|
-
//=> 111
|
|
1119
|
-
|
|
1120
|
-
Subtract<111, -222>;
|
|
1121
|
-
//=> 333
|
|
1122
|
-
|
|
1123
|
-
Subtract<-111, 222>;
|
|
1124
|
-
//=> -333
|
|
1125
|
-
|
|
1126
|
-
Subtract<18, 96>;
|
|
1127
|
-
//=> -78
|
|
1128
|
-
|
|
1129
|
-
Subtract<PositiveInfinity, 9999>;
|
|
1130
|
-
//=> PositiveInfinity
|
|
1131
|
-
|
|
1132
|
-
Subtract<PositiveInfinity, PositiveInfinity>;
|
|
1133
|
-
//=> number
|
|
1134
|
-
```
|
|
1135
|
-
|
|
1136
|
-
@category Numeric
|
|
1137
|
-
*/
|
|
1138
|
-
// TODO: Support big integer.
|
|
1139
|
-
type Subtract<A extends number, B extends number> =
|
|
1140
|
-
// Handle cases when A or B is the actual "number" type
|
|
1141
|
-
number extends A | B ? number
|
|
1142
|
-
// Handle cases when A and B are both +/- infinity
|
|
1143
|
-
: A extends B & (PositiveInfinity | NegativeInfinity) ? number
|
|
1144
|
-
// Handle cases when A is - infinity or B is + infinity
|
|
1145
|
-
: A extends NegativeInfinity ? NegativeInfinity : B extends PositiveInfinity ? NegativeInfinity
|
|
1146
|
-
// Handle cases when A is + infinity or B is - infinity
|
|
1147
|
-
: A extends PositiveInfinity ? PositiveInfinity : B extends NegativeInfinity ? PositiveInfinity
|
|
1148
|
-
// Handle case when numbers are equal to each other
|
|
1149
|
-
: A extends B ? 0
|
|
1150
|
-
// Handle cases when A or B is 0
|
|
1151
|
-
: A extends 0 ? ReverseSign<B> : B extends 0 ? A
|
|
1152
|
-
// Handle remaining regular cases
|
|
1153
|
-
: SubtractPostChecks<A, B>;
|
|
1154
|
-
|
|
1155
|
-
/**
|
|
1156
|
-
Subtracts two numbers A and B, such that they are not equal and neither of them are 0, +/- infinity or the `number` type
|
|
1157
|
-
*/
|
|
1158
|
-
type SubtractPostChecks<A extends number, B extends number, AreNegative = [IsNegative<A>, IsNegative<B>]> =
|
|
1159
|
-
AreNegative extends [false, false]
|
|
1160
|
-
? SubtractPositives<A, B>
|
|
1161
|
-
: AreNegative extends [true, true]
|
|
1162
|
-
// When both numbers are negative we subtract the absolute values and then reverse the sign
|
|
1163
|
-
? ReverseSign<SubtractPositives<NumberAbsolute<A>, NumberAbsolute<B>>>
|
|
1164
|
-
// When the signs are different we can add the absolute values and then reverse the sign if A < B
|
|
1165
|
-
: [...BuildTuple<NumberAbsolute<A>>, ...BuildTuple<NumberAbsolute<B>>] extends infer R extends unknown[]
|
|
1166
|
-
? LessThan<A, B> extends true ? ReverseSign<R['length']> : R['length']
|
|
1167
|
-
: never;
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
Subtracts two positive numbers.
|
|
1171
|
-
*/
|
|
1172
|
-
type SubtractPositives<A extends number, B extends number> =
|
|
1173
|
-
LessThan<A, B> extends true
|
|
1174
|
-
// When A < B we can reverse the result of B - A
|
|
1175
|
-
? ReverseSign<SubtractIfAGreaterThanB<B, A>>
|
|
1176
|
-
: SubtractIfAGreaterThanB<A, B>;
|
|
1177
|
-
|
|
1178
|
-
/**
|
|
1179
|
-
Subtracts two positive numbers A and B such that A > B.
|
|
1180
|
-
*/
|
|
1181
|
-
type SubtractIfAGreaterThanB<A extends number, B extends number> =
|
|
1182
|
-
// This is where we always want to end up and do the actual subtraction
|
|
1183
|
-
BuildTuple<A> extends [...BuildTuple<B>, ...infer R]
|
|
1184
|
-
? R['length']
|
|
1185
|
-
: never;
|
|
1186
|
-
|
|
1187
|
-
/**
|
|
1188
|
-
Paths options.
|
|
1189
|
-
|
|
1190
|
-
@see {@link Paths}
|
|
1191
|
-
*/
|
|
1192
|
-
type PathsOptions = {
|
|
1193
|
-
/**
|
|
1194
|
-
The maximum depth to recurse when searching for paths.
|
|
1195
|
-
|
|
1196
|
-
@default 10
|
|
1197
|
-
*/
|
|
1198
|
-
maxRecursionDepth?: number;
|
|
1199
|
-
|
|
1200
|
-
/**
|
|
1201
|
-
Use bracket notation for array indices and numeric object keys.
|
|
1202
|
-
|
|
1203
|
-
@default false
|
|
1204
|
-
|
|
1205
|
-
@example
|
|
1206
|
-
```
|
|
1207
|
-
type ArrayExample = {
|
|
1208
|
-
array: ['foo'];
|
|
1209
|
-
};
|
|
1210
|
-
|
|
1211
|
-
type A = Paths<ArrayExample, {bracketNotation: false}>;
|
|
1212
|
-
//=> 'array' | 'array.0'
|
|
1213
|
-
|
|
1214
|
-
type B = Paths<ArrayExample, {bracketNotation: true}>;
|
|
1215
|
-
//=> 'array' | 'array[0]'
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
@example
|
|
1219
|
-
```
|
|
1220
|
-
type NumberKeyExample = {
|
|
1221
|
-
1: ['foo'];
|
|
1222
|
-
};
|
|
1223
|
-
|
|
1224
|
-
type A = Paths<NumberKeyExample, {bracketNotation: false}>;
|
|
1225
|
-
//=> 1 | '1' | '1.0'
|
|
1226
|
-
|
|
1227
|
-
type B = Paths<NumberKeyExample, {bracketNotation: true}>;
|
|
1228
|
-
//=> '[1]' | '[1][0]'
|
|
1229
|
-
```
|
|
1230
|
-
*/
|
|
1231
|
-
bracketNotation?: boolean;
|
|
1232
|
-
|
|
1233
|
-
/**
|
|
1234
|
-
Only include leaf paths in the output.
|
|
1235
|
-
|
|
1236
|
-
@default false
|
|
1237
|
-
|
|
1238
|
-
@example
|
|
1239
|
-
```
|
|
1240
|
-
type Post = {
|
|
1241
|
-
id: number;
|
|
1242
|
-
author: {
|
|
1243
|
-
id: number;
|
|
1244
|
-
name: {
|
|
1245
|
-
first: string;
|
|
1246
|
-
last: string;
|
|
1247
|
-
};
|
|
1248
|
-
};
|
|
1249
|
-
};
|
|
1250
|
-
|
|
1251
|
-
type AllPaths = Paths<Post, {leavesOnly: false}>;
|
|
1252
|
-
//=> 'id' | 'author' | 'author.id' | 'author.name' | 'author.name.first' | 'author.name.last'
|
|
1253
|
-
|
|
1254
|
-
type LeafPaths = Paths<Post, {leavesOnly: true}>;
|
|
1255
|
-
//=> 'id' | 'author.id' | 'author.name.first' | 'author.name.last'
|
|
1256
|
-
```
|
|
1257
|
-
|
|
1258
|
-
@example
|
|
1259
|
-
```
|
|
1260
|
-
type ArrayExample = {
|
|
1261
|
-
array: Array<{foo: string}>;
|
|
1262
|
-
tuple: [string, {bar: string}];
|
|
1263
|
-
};
|
|
1264
|
-
|
|
1265
|
-
type AllPaths = Paths<ArrayExample, {leavesOnly: false}>;
|
|
1266
|
-
//=> 'array' | `array.${number}` | `array.${number}.foo` | 'tuple' | 'tuple.0' | 'tuple.1' | 'tuple.1.bar'
|
|
1267
|
-
|
|
1268
|
-
type LeafPaths = Paths<ArrayExample, {leavesOnly: true}>;
|
|
1269
|
-
//=> `array.${number}.foo` | 'tuple.0' | 'tuple.1.bar'
|
|
1270
|
-
```
|
|
1271
|
-
*/
|
|
1272
|
-
leavesOnly?: boolean;
|
|
1273
|
-
|
|
1274
|
-
/**
|
|
1275
|
-
Only include paths at the specified depth. By default all paths up to {@link PathsOptions.maxRecursionDepth | `maxRecursionDepth`} are included.
|
|
1276
|
-
|
|
1277
|
-
Note: Depth starts at `0` for root properties.
|
|
1278
|
-
|
|
1279
|
-
@default number
|
|
1280
|
-
|
|
1281
|
-
@example
|
|
1282
|
-
```
|
|
1283
|
-
type Post = {
|
|
1284
|
-
id: number;
|
|
1285
|
-
author: {
|
|
1286
|
-
id: number;
|
|
1287
|
-
name: {
|
|
1288
|
-
first: string;
|
|
1289
|
-
last: string;
|
|
1290
|
-
};
|
|
1291
|
-
};
|
|
1292
|
-
};
|
|
1293
|
-
|
|
1294
|
-
type DepthZero = Paths<Post, {depth: 0}>;
|
|
1295
|
-
//=> 'id' | 'author'
|
|
1296
|
-
|
|
1297
|
-
type DepthOne = Paths<Post, {depth: 1}>;
|
|
1298
|
-
//=> 'author.id' | 'author.name'
|
|
1299
|
-
|
|
1300
|
-
type DepthTwo = Paths<Post, {depth: 2}>;
|
|
1301
|
-
//=> 'author.name.first' | 'author.name.last'
|
|
1302
|
-
|
|
1303
|
-
type LeavesAtDepthOne = Paths<Post, {leavesOnly: true; depth: 1}>;
|
|
1304
|
-
//=> 'author.id'
|
|
1305
|
-
```
|
|
1306
|
-
*/
|
|
1307
|
-
depth?: number;
|
|
1308
|
-
};
|
|
1309
|
-
|
|
1310
|
-
type DefaultPathsOptions = {
|
|
1311
|
-
maxRecursionDepth: 10;
|
|
1312
|
-
bracketNotation: false;
|
|
1313
|
-
leavesOnly: false;
|
|
1314
|
-
depth: number;
|
|
1315
|
-
};
|
|
1316
|
-
|
|
1317
|
-
/**
|
|
1318
|
-
Generate a union of all possible paths to properties in the given object.
|
|
1319
|
-
|
|
1320
|
-
It also works with arrays.
|
|
1321
|
-
|
|
1322
|
-
Use-case: You want a type-safe way to access deeply nested properties in an object.
|
|
1323
|
-
|
|
1324
|
-
@example
|
|
1325
|
-
```
|
|
1326
|
-
import type {Paths} from 'type-fest';
|
|
1327
|
-
|
|
1328
|
-
type Project = {
|
|
1329
|
-
filename: string;
|
|
1330
|
-
listA: string[];
|
|
1331
|
-
listB: [{filename: string}];
|
|
1332
|
-
folder: {
|
|
1333
|
-
subfolder: {
|
|
1334
|
-
filename: string;
|
|
1335
|
-
};
|
|
1336
|
-
};
|
|
1337
|
-
};
|
|
1338
|
-
|
|
1339
|
-
type ProjectPaths = Paths<Project>;
|
|
1340
|
-
//=> 'filename' | 'listA' | 'listB' | 'folder' | `listA.${number}` | 'listB.0' | 'listB.0.filename' | 'folder.subfolder' | 'folder.subfolder.filename'
|
|
1341
|
-
|
|
1342
|
-
declare function open<Path extends ProjectPaths>(path: Path): void;
|
|
1343
|
-
|
|
1344
|
-
open('filename'); // Pass
|
|
1345
|
-
open('folder.subfolder'); // Pass
|
|
1346
|
-
open('folder.subfolder.filename'); // Pass
|
|
1347
|
-
open('foo'); // TypeError
|
|
1348
|
-
|
|
1349
|
-
// Also works with arrays
|
|
1350
|
-
open('listA.1'); // Pass
|
|
1351
|
-
open('listB.0'); // Pass
|
|
1352
|
-
open('listB.1'); // TypeError. Because listB only has one element.
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
@category Object
|
|
1356
|
-
@category Array
|
|
1357
|
-
*/
|
|
1358
|
-
type Paths<T, Options extends PathsOptions = {}> = _Paths<T, {
|
|
1359
|
-
// Set default maxRecursionDepth to 10
|
|
1360
|
-
maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth'];
|
|
1361
|
-
// Set default bracketNotation to false
|
|
1362
|
-
bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation'];
|
|
1363
|
-
// Set default leavesOnly to false
|
|
1364
|
-
leavesOnly: Options['leavesOnly'] extends boolean ? Options['leavesOnly'] : DefaultPathsOptions['leavesOnly'];
|
|
1365
|
-
// Set default depth to number
|
|
1366
|
-
depth: Options['depth'] extends number ? Options['depth'] : DefaultPathsOptions['depth'];
|
|
1367
|
-
}>;
|
|
1368
|
-
|
|
1369
|
-
type _Paths<T, Options extends Required<PathsOptions>> =
|
|
1370
|
-
T extends NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
|
|
1371
|
-
? never
|
|
1372
|
-
: IsAny<T> extends true
|
|
1373
|
-
? never
|
|
1374
|
-
: T extends UnknownArray
|
|
1375
|
-
? number extends T['length']
|
|
1376
|
-
// We need to handle the fixed and non-fixed index part of the array separately.
|
|
1377
|
-
? InternalPaths<StaticPartOfArray<T>, Options>
|
|
1378
|
-
| InternalPaths<Array<VariablePartOfArray<T>[number]>, Options>
|
|
1379
|
-
: InternalPaths<T, Options>
|
|
1380
|
-
: T extends object
|
|
1381
|
-
? InternalPaths<T, Options>
|
|
1382
|
-
: never;
|
|
1383
|
-
|
|
1384
|
-
type InternalPaths<T, Options extends Required<PathsOptions>> =
|
|
1385
|
-
Options['maxRecursionDepth'] extends infer MaxDepth extends number
|
|
1386
|
-
? Required<T> extends infer T
|
|
1387
|
-
? T extends EmptyObject | readonly []
|
|
1388
|
-
? never
|
|
1389
|
-
: {
|
|
1390
|
-
[Key in keyof T]:
|
|
1391
|
-
Key extends string | number // Limit `Key` to string or number.
|
|
1392
|
-
? (
|
|
1393
|
-
Options['bracketNotation'] extends true
|
|
1394
|
-
? IsNumberLike<Key> extends true
|
|
1395
|
-
? `[${Key}]`
|
|
1396
|
-
: (Key | ToString<Key>)
|
|
1397
|
-
: never
|
|
1398
|
-
|
|
|
1399
|
-
Options['bracketNotation'] extends false
|
|
1400
|
-
// If `Key` is a number, return `Key | `${Key}``, because both `array[0]` and `array['0']` work.
|
|
1401
|
-
? (Key | ToString<Key>)
|
|
1402
|
-
: never
|
|
1403
|
-
) extends infer TranformedKey extends string | number ?
|
|
1404
|
-
// 1. If style is 'a[0].b' and 'Key' is a numberlike value like 3 or '3', transform 'Key' to `[${Key}]`, else to `${Key}` | Key
|
|
1405
|
-
// 2. If style is 'a.0.b', transform 'Key' to `${Key}` | Key
|
|
1406
|
-
| ((Options['leavesOnly'] extends true
|
|
1407
|
-
? MaxDepth extends 0
|
|
1408
|
-
? TranformedKey
|
|
1409
|
-
: T[Key] extends EmptyObject | readonly [] | NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
|
|
1410
|
-
? TranformedKey
|
|
1411
|
-
: never
|
|
1412
|
-
: TranformedKey
|
|
1413
|
-
) extends infer _TransformedKey
|
|
1414
|
-
// If `depth` is provided, the condition becomes truthy only when it reaches `0`.
|
|
1415
|
-
// Otherwise, since `depth` defaults to `number`, the condition is always truthy, returning paths at all depths.
|
|
1416
|
-
? 0 extends Options['depth']
|
|
1417
|
-
? _TransformedKey
|
|
1418
|
-
: never
|
|
1419
|
-
: never)
|
|
1420
|
-
| (
|
|
1421
|
-
// Recursively generate paths for the current key
|
|
1422
|
-
GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
|
|
1423
|
-
? _Paths<T[Key],
|
|
1424
|
-
{
|
|
1425
|
-
bracketNotation: Options['bracketNotation'];
|
|
1426
|
-
maxRecursionDepth: Subtract<MaxDepth, 1>;
|
|
1427
|
-
leavesOnly: Options['leavesOnly'];
|
|
1428
|
-
depth: Subtract<Options['depth'], 1>;
|
|
1429
|
-
}> extends infer SubPath
|
|
1430
|
-
? SubPath extends string | number
|
|
1431
|
-
? (
|
|
1432
|
-
Options['bracketNotation'] extends true
|
|
1433
|
-
? SubPath extends `[${any}]` | `[${any}]${string}`
|
|
1434
|
-
? `${TranformedKey}${SubPath}` // If next node is number key like `[3]`, no need to add `.` before it.
|
|
1435
|
-
: `${TranformedKey}.${SubPath}`
|
|
1436
|
-
: never
|
|
1437
|
-
) | (
|
|
1438
|
-
Options['bracketNotation'] extends false
|
|
1439
|
-
? `${TranformedKey}.${SubPath}`
|
|
1440
|
-
: never
|
|
1441
|
-
)
|
|
1442
|
-
: never
|
|
1443
|
-
: never
|
|
1444
|
-
: never
|
|
1445
|
-
)
|
|
1446
|
-
: never
|
|
1447
|
-
: never
|
|
1448
|
-
}[keyof T & (T extends UnknownArray ? number : unknown)]
|
|
1449
|
-
: never
|
|
1450
|
-
: never;
|
|
1451
|
-
|
|
1452
|
-
/**
|
|
1453
|
-
Pick properties from a deeply-nested object.
|
|
1454
|
-
|
|
1455
|
-
It supports recursing into arrays.
|
|
1456
|
-
|
|
1457
|
-
Use-case: Distill complex objects down to the components you need to target.
|
|
1458
|
-
|
|
1459
|
-
@example
|
|
1460
|
-
```
|
|
1461
|
-
import type {PickDeep, PartialDeep} from 'type-fest';
|
|
1462
|
-
|
|
1463
|
-
type Configuration = {
|
|
1464
|
-
userConfig: {
|
|
1465
|
-
name: string;
|
|
1466
|
-
age: number;
|
|
1467
|
-
address: [
|
|
1468
|
-
{
|
|
1469
|
-
city1: string;
|
|
1470
|
-
street1: string;
|
|
1471
|
-
},
|
|
1472
|
-
{
|
|
1473
|
-
city2: string;
|
|
1474
|
-
street2: string;
|
|
1475
|
-
}
|
|
1476
|
-
]
|
|
1477
|
-
};
|
|
1478
|
-
otherConfig: any;
|
|
1479
|
-
};
|
|
1480
|
-
|
|
1481
|
-
type NameConfig = PickDeep<Configuration, 'userConfig.name'>;
|
|
1482
|
-
// type NameConfig = {
|
|
1483
|
-
// userConfig: {
|
|
1484
|
-
// name: string;
|
|
1485
|
-
// }
|
|
1486
|
-
// };
|
|
1487
|
-
|
|
1488
|
-
// Supports optional properties
|
|
1489
|
-
type User = PickDeep<PartialDeep<Configuration>, 'userConfig.name' | 'userConfig.age'>;
|
|
1490
|
-
// type User = {
|
|
1491
|
-
// userConfig?: {
|
|
1492
|
-
// name?: string;
|
|
1493
|
-
// age?: number;
|
|
1494
|
-
// };
|
|
1495
|
-
// };
|
|
1496
|
-
|
|
1497
|
-
// Supports array
|
|
1498
|
-
type AddressConfig = PickDeep<Configuration, 'userConfig.address.0'>;
|
|
1499
|
-
// type AddressConfig = {
|
|
1500
|
-
// userConfig: {
|
|
1501
|
-
// address: [{
|
|
1502
|
-
// city1: string;
|
|
1503
|
-
// street1: string;
|
|
1504
|
-
// }];
|
|
1505
|
-
// };
|
|
1506
|
-
// }
|
|
1507
|
-
|
|
1508
|
-
// Supports recurse into array
|
|
1509
|
-
type Street = PickDeep<Configuration, 'userConfig.address.1.street2'>;
|
|
1510
|
-
// type Street = {
|
|
1511
|
-
// userConfig: {
|
|
1512
|
-
// address: [
|
|
1513
|
-
// unknown,
|
|
1514
|
-
// {street2: string}
|
|
1515
|
-
// ];
|
|
1516
|
-
// };
|
|
1517
|
-
// }
|
|
1518
|
-
```
|
|
1519
|
-
|
|
1520
|
-
@category Object
|
|
1521
|
-
@category Array
|
|
1522
|
-
*/
|
|
1523
|
-
type PickDeep<T, PathUnion extends Paths<T>> =
|
|
1524
|
-
T extends NonRecursiveType
|
|
1525
|
-
? never
|
|
1526
|
-
: T extends UnknownArray
|
|
1527
|
-
? UnionToIntersection<{
|
|
1528
|
-
[P in PathUnion]: InternalPickDeep<T, P>;
|
|
1529
|
-
}[PathUnion]
|
|
1530
|
-
>
|
|
1531
|
-
: T extends object
|
|
1532
|
-
? Simplify<UnionToIntersection<{
|
|
1533
|
-
[P in PathUnion]: InternalPickDeep<T, P>;
|
|
1534
|
-
}[PathUnion]>>
|
|
1535
|
-
: never;
|
|
1536
|
-
|
|
1537
|
-
/**
|
|
1538
|
-
Pick an object/array from the given object/array by one path.
|
|
1539
|
-
*/
|
|
1540
|
-
type InternalPickDeep<T, Path extends string | number> =
|
|
1541
|
-
T extends NonRecursiveType
|
|
1542
|
-
? never
|
|
1543
|
-
: T extends UnknownArray ? PickDeepArray<T, Path>
|
|
1544
|
-
: T extends object ? Simplify<PickDeepObject<T, Path>>
|
|
1545
|
-
: never;
|
|
1546
|
-
|
|
1547
|
-
/**
|
|
1548
|
-
Pick an object from the given object by one path.
|
|
1549
|
-
*/
|
|
1550
|
-
type PickDeepObject<RecordType extends object, P extends string | number> =
|
|
1551
|
-
P extends `${infer RecordKeyInPath}.${infer SubPath}`
|
|
1552
|
-
? ObjectValue<RecordType, RecordKeyInPath> extends infer ObjectV
|
|
1553
|
-
? IsNever<ObjectV> extends false
|
|
1554
|
-
? BuildObject<RecordKeyInPath, InternalPickDeep<NonNullable<ObjectV>, SubPath>, RecordType>
|
|
1555
|
-
: never
|
|
1556
|
-
: never
|
|
1557
|
-
: ObjectValue<RecordType, P> extends infer ObjectV
|
|
1558
|
-
? IsNever<ObjectV> extends false
|
|
1559
|
-
? BuildObject<P, ObjectV, RecordType>
|
|
1560
|
-
: never
|
|
1561
|
-
: never;
|
|
1562
|
-
|
|
1563
|
-
/**
|
|
1564
|
-
Pick an array from the given array by one path.
|
|
1565
|
-
*/
|
|
1566
|
-
type PickDeepArray<ArrayType extends UnknownArray, P extends string | number> =
|
|
1567
|
-
// Handle paths that are `${number}.${string}`
|
|
1568
|
-
P extends `${infer ArrayIndex extends number}.${infer SubPath}`
|
|
1569
|
-
// When `ArrayIndex` is equal to `number`
|
|
1570
|
-
? number extends ArrayIndex
|
|
1571
|
-
? ArrayType extends unknown[]
|
|
1572
|
-
? Array<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
|
|
1573
|
-
: ArrayType extends readonly unknown[]
|
|
1574
|
-
? ReadonlyArray<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
|
|
1575
|
-
: never
|
|
1576
|
-
// When `ArrayIndex` is a number literal
|
|
1577
|
-
: ArrayType extends unknown[]
|
|
1578
|
-
? [...BuildTuple<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
|
|
1579
|
-
: ArrayType extends readonly unknown[]
|
|
1580
|
-
? readonly [...BuildTuple<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
|
|
1581
|
-
: never
|
|
1582
|
-
// When the path is equal to `number`
|
|
1583
|
-
: P extends `${infer ArrayIndex extends number}`
|
|
1584
|
-
// When `ArrayIndex` is `number`
|
|
1585
|
-
? number extends ArrayIndex
|
|
1586
|
-
? ArrayType
|
|
1587
|
-
// When `ArrayIndex` is a number literal
|
|
1588
|
-
: ArrayType extends unknown[]
|
|
1589
|
-
? [...BuildTuple<ArrayIndex>, ArrayType[ArrayIndex]]
|
|
1590
|
-
: ArrayType extends readonly unknown[]
|
|
1591
|
-
? readonly [...BuildTuple<ArrayIndex>, ArrayType[ArrayIndex]]
|
|
1592
|
-
: never
|
|
1593
|
-
: never;
|
|
1594
|
-
|
|
1595
|
-
/**
|
|
1596
|
-
The implementation of `SplitArrayByIndex` for fixed length arrays.
|
|
1597
|
-
*/
|
|
1598
|
-
type SplitFixedArrayByIndex<T extends UnknownArray, SplitIndex extends number> =
|
|
1599
|
-
SplitIndex extends 0
|
|
1600
|
-
? [[], T]
|
|
1601
|
-
: T extends readonly [...BuildTuple<SplitIndex>, ...infer V]
|
|
1602
|
-
? T extends readonly [...infer U, ...V]
|
|
1603
|
-
? [U, V]
|
|
1604
|
-
: [never, never]
|
|
1605
|
-
: [never, never];
|
|
1606
|
-
|
|
1607
|
-
/**
|
|
1608
|
-
The implementation of `SplitArrayByIndex` for variable length arrays.
|
|
1609
|
-
*/
|
|
1610
|
-
type SplitVariableArrayByIndex<T extends UnknownArray,
|
|
1611
|
-
SplitIndex extends number,
|
|
1612
|
-
T1 = Subtract<SplitIndex, StaticPartOfArray<T>['length']>,
|
|
1613
|
-
T2 = T1 extends number
|
|
1614
|
-
? BuildTuple<GreaterThanOrEqual<T1, 0> extends true ? T1 : number, VariablePartOfArray<T>[number]>
|
|
1615
|
-
: [],
|
|
1616
|
-
> =
|
|
1617
|
-
SplitIndex extends 0
|
|
1618
|
-
? [[], T]
|
|
1619
|
-
: GreaterThanOrEqual<StaticPartOfArray<T>['length'], SplitIndex> extends true
|
|
1620
|
-
? [
|
|
1621
|
-
SplitFixedArrayByIndex<StaticPartOfArray<T>, SplitIndex>[0],
|
|
1622
|
-
[
|
|
1623
|
-
...SplitFixedArrayByIndex<StaticPartOfArray<T>, SplitIndex>[1],
|
|
1624
|
-
...VariablePartOfArray<T>,
|
|
1625
|
-
],
|
|
1626
|
-
]
|
|
1627
|
-
: [
|
|
1628
|
-
[
|
|
1629
|
-
...StaticPartOfArray<T>,
|
|
1630
|
-
...(T2 extends UnknownArray ? T2 : []),
|
|
1631
|
-
],
|
|
1632
|
-
VariablePartOfArray<T>,
|
|
1633
|
-
];
|
|
1634
|
-
|
|
1635
|
-
/**
|
|
1636
|
-
Split the given array `T` by the given `SplitIndex`.
|
|
1637
|
-
|
|
1638
|
-
@example
|
|
1639
|
-
```
|
|
1640
|
-
type A = SplitArrayByIndex<[1, 2, 3, 4], 2>;
|
|
1641
|
-
// type A = [[1, 2], [3, 4]];
|
|
1642
|
-
|
|
1643
|
-
type B = SplitArrayByIndex<[1, 2, 3, 4], 0>;
|
|
1644
|
-
// type B = [[], [1, 2, 3, 4]];
|
|
1645
|
-
```
|
|
1646
|
-
*/
|
|
1647
|
-
type SplitArrayByIndex<T extends UnknownArray, SplitIndex extends number> =
|
|
1648
|
-
SplitIndex extends 0
|
|
1649
|
-
? [[], T]
|
|
1650
|
-
: number extends T['length']
|
|
1651
|
-
? SplitVariableArrayByIndex<T, SplitIndex>
|
|
1652
|
-
: SplitFixedArrayByIndex<T, SplitIndex>;
|
|
1653
|
-
|
|
1654
|
-
/**
|
|
1655
|
-
Creates a new array type by adding or removing elements at a specified index range in the original array.
|
|
1656
|
-
|
|
1657
|
-
Use-case: Replace or insert items in an array type.
|
|
1658
|
-
|
|
1659
|
-
Like [`Array#splice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) but for types.
|
|
1660
|
-
|
|
1661
|
-
@example
|
|
1662
|
-
```
|
|
1663
|
-
type SomeMonths0 = ['January', 'April', 'June'];
|
|
1664
|
-
type Mouths0 = ArraySplice<SomeMonths0, 1, 0, ['Feb', 'March']>;
|
|
1665
|
-
//=> type Mouths0 = ['January', 'Feb', 'March', 'April', 'June'];
|
|
1666
|
-
|
|
1667
|
-
type SomeMonths1 = ['January', 'April', 'June'];
|
|
1668
|
-
type Mouths1 = ArraySplice<SomeMonths1, 1, 1>;
|
|
1669
|
-
//=> type Mouths1 = ['January', 'June'];
|
|
1670
|
-
|
|
1671
|
-
type SomeMonths2 = ['January', 'Foo', 'April'];
|
|
1672
|
-
type Mouths2 = ArraySplice<SomeMonths2, 1, 1, ['Feb', 'March']>;
|
|
1673
|
-
//=> type Mouths2 = ['January', 'Feb', 'March', 'April'];
|
|
1674
|
-
```
|
|
1675
|
-
|
|
1676
|
-
@category Array
|
|
1677
|
-
*/
|
|
1678
|
-
type ArraySplice<
|
|
1679
|
-
T extends UnknownArray,
|
|
1680
|
-
Start extends number,
|
|
1681
|
-
DeleteCount extends number,
|
|
1682
|
-
Items extends UnknownArray = [],
|
|
1683
|
-
> =
|
|
1684
|
-
SplitArrayByIndex<T, Start> extends [infer U extends UnknownArray, infer V extends UnknownArray]
|
|
1685
|
-
? SplitArrayByIndex<V, DeleteCount> extends [infer _Deleted extends UnknownArray, infer X extends UnknownArray]
|
|
1686
|
-
? [...U, ...Items, ...X]
|
|
1687
|
-
: never // Should never happen
|
|
1688
|
-
: never; // Should never happen
|
|
1689
|
-
|
|
1690
|
-
type LiteralStringUnion<T> = LiteralUnion<T, string>;
|
|
1691
|
-
|
|
1692
|
-
/**
|
|
1693
|
-
Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
|
|
1694
|
-
|
|
1695
|
-
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.
|
|
1696
|
-
|
|
1697
|
-
This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.
|
|
1698
|
-
|
|
1699
|
-
@example
|
|
1700
|
-
```
|
|
1701
|
-
import type {LiteralUnion} from 'type-fest';
|
|
1702
|
-
|
|
1703
|
-
// Before
|
|
1704
|
-
|
|
1705
|
-
type Pet = 'dog' | 'cat' | string;
|
|
1706
|
-
|
|
1707
|
-
const pet: Pet = '';
|
|
1708
|
-
// Start typing in your TypeScript-enabled IDE.
|
|
1709
|
-
// You **will not** get auto-completion for `dog` and `cat` literals.
|
|
1710
|
-
|
|
1711
|
-
// After
|
|
1712
|
-
|
|
1713
|
-
type Pet2 = LiteralUnion<'dog' | 'cat', string>;
|
|
1714
|
-
|
|
1715
|
-
const pet: Pet2 = '';
|
|
1716
|
-
// You **will** get auto-completion for `dog` and `cat` literals.
|
|
1717
|
-
```
|
|
1718
|
-
|
|
1719
|
-
@category Type
|
|
1720
|
-
*/
|
|
1721
|
-
type LiteralUnion<
|
|
1722
|
-
LiteralType,
|
|
1723
|
-
BaseType extends Primitive,
|
|
1724
|
-
> = LiteralType | (BaseType & Record<never, never>);
|
|
1725
|
-
|
|
1726
|
-
/**
|
|
1727
|
-
Returns the last element of a union type.
|
|
1728
|
-
|
|
1729
|
-
@example
|
|
1730
|
-
```
|
|
1731
|
-
type Last = LastOfUnion<1 | 2 | 3>;
|
|
1732
|
-
//=> 3
|
|
1733
|
-
```
|
|
1734
|
-
*/
|
|
1735
|
-
type LastOfUnion<T> =
|
|
1736
|
-
UnionToIntersection<T extends any ? () => T : never> extends () => (infer R)
|
|
1737
|
-
? R
|
|
1738
|
-
: never;
|
|
1739
|
-
|
|
1740
|
-
/**
|
|
1741
|
-
Convert a union type into an unordered tuple type of its elements.
|
|
1742
|
-
|
|
1743
|
-
"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.
|
|
1744
|
-
|
|
1745
|
-
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.
|
|
1746
|
-
|
|
1747
|
-
@example
|
|
1748
|
-
```
|
|
1749
|
-
import type {UnionToTuple} from 'type-fest';
|
|
1750
|
-
|
|
1751
|
-
type Numbers = 1 | 2 | 3;
|
|
1752
|
-
type NumbersTuple = UnionToTuple<Numbers>;
|
|
1753
|
-
//=> [1, 2, 3]
|
|
1754
|
-
```
|
|
1755
|
-
|
|
1756
|
-
@example
|
|
1757
|
-
```
|
|
1758
|
-
import type {UnionToTuple} from 'type-fest';
|
|
1759
|
-
|
|
1760
|
-
const pets = {
|
|
1761
|
-
dog: 'πΆ',
|
|
1762
|
-
cat: 'π±',
|
|
1763
|
-
snake: 'π',
|
|
1764
|
-
};
|
|
1765
|
-
|
|
1766
|
-
type Pet = keyof typeof pets;
|
|
1767
|
-
//=> 'dog' | 'cat' | 'snake'
|
|
1768
|
-
|
|
1769
|
-
const petList = Object.keys(pets) as UnionToTuple<Pet>;
|
|
1770
|
-
//=> ['dog', 'cat', 'snake']
|
|
1771
|
-
```
|
|
1772
|
-
|
|
1773
|
-
@category Array
|
|
1774
|
-
*/
|
|
1775
|
-
type UnionToTuple<T, L = LastOfUnion<T>> =
|
|
1776
|
-
IsNever<T> extends false
|
|
1777
|
-
? [...UnionToTuple<Exclude<T, L>>, L]
|
|
1778
|
-
: [];
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
Omit properties from a deeply-nested object.
|
|
1782
|
-
|
|
1783
|
-
It supports recursing into arrays.
|
|
1784
|
-
|
|
1785
|
-
It supports removing specific items from an array, replacing each removed item with unknown at the specified index.
|
|
1786
|
-
|
|
1787
|
-
Use-case: Remove unneeded parts of complex objects.
|
|
1788
|
-
|
|
1789
|
-
Use [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) if you only need one level deep.
|
|
1790
|
-
|
|
1791
|
-
@example
|
|
1792
|
-
```
|
|
1793
|
-
import type {OmitDeep} from 'type-fest';
|
|
1794
|
-
|
|
1795
|
-
type Info = {
|
|
1796
|
-
userInfo: {
|
|
1797
|
-
name: string;
|
|
1798
|
-
uselessInfo: {
|
|
1799
|
-
foo: string;
|
|
1800
|
-
};
|
|
1801
|
-
};
|
|
1802
|
-
};
|
|
1803
|
-
|
|
1804
|
-
type UsefulInfo = OmitDeep<Info, 'userInfo.uselessInfo'>;
|
|
1805
|
-
// type UsefulInfo = {
|
|
1806
|
-
// userInfo: {
|
|
1807
|
-
// name: string;
|
|
1808
|
-
// };
|
|
1809
|
-
// };
|
|
1810
|
-
|
|
1811
|
-
// Supports removing multiple paths
|
|
1812
|
-
type Info1 = {
|
|
1813
|
-
userInfo: {
|
|
1814
|
-
name: string;
|
|
1815
|
-
uselessField: string;
|
|
1816
|
-
uselessInfo: {
|
|
1817
|
-
foo: string;
|
|
1818
|
-
};
|
|
1819
|
-
};
|
|
1820
|
-
};
|
|
1821
|
-
|
|
1822
|
-
type UsefulInfo1 = OmitDeep<Info1, 'userInfo.uselessInfo' | 'userInfo.uselessField'>;
|
|
1823
|
-
// type UsefulInfo1 = {
|
|
1824
|
-
// userInfo: {
|
|
1825
|
-
// name: string;
|
|
1826
|
-
// };
|
|
1827
|
-
// };
|
|
1828
|
-
|
|
1829
|
-
// Supports array
|
|
1830
|
-
type A = OmitDeep<[1, 'foo', 2], 1>;
|
|
1831
|
-
// type A = [1, unknown, 2];
|
|
1832
|
-
|
|
1833
|
-
// Supports recursing into array
|
|
1834
|
-
|
|
1835
|
-
type Info1 = {
|
|
1836
|
-
address: [
|
|
1837
|
-
{
|
|
1838
|
-
street: string
|
|
1839
|
-
},
|
|
1840
|
-
{
|
|
1841
|
-
street2: string,
|
|
1842
|
-
foo: string
|
|
1843
|
-
};
|
|
1844
|
-
];
|
|
1845
|
-
}
|
|
1846
|
-
type AddressInfo = OmitDeep<Info1, 'address.1.foo'>;
|
|
1847
|
-
// type AddressInfo = {
|
|
1848
|
-
// address: [
|
|
1849
|
-
// {
|
|
1850
|
-
// street: string;
|
|
1851
|
-
// },
|
|
1852
|
-
// {
|
|
1853
|
-
// street2: string;
|
|
1854
|
-
// };
|
|
1855
|
-
// ];
|
|
1856
|
-
// };
|
|
1857
|
-
```
|
|
1858
|
-
|
|
1859
|
-
@category Object
|
|
1860
|
-
@category Array
|
|
1861
|
-
*/
|
|
1862
|
-
type OmitDeep<T, PathUnion extends LiteralUnion<Paths<T>, string>> =
|
|
1863
|
-
SimplifyDeep<
|
|
1864
|
-
OmitDeepHelper<T, UnionToTuple<PathUnion>>,
|
|
1865
|
-
UnknownArray>;
|
|
1866
|
-
|
|
1867
|
-
/**
|
|
1868
|
-
Internal helper for {@link OmitDeep}.
|
|
1869
|
-
|
|
1870
|
-
Recursively transforms `T` by applying {@link OmitDeepWithOnePath} for each path in `PathTuple`.
|
|
1871
|
-
*/
|
|
1872
|
-
type OmitDeepHelper<T, PathTuple extends UnknownArray> =
|
|
1873
|
-
PathTuple extends [infer Path, ...infer RestPaths]
|
|
1874
|
-
? OmitDeepHelper<OmitDeepWithOnePath<T, Path & (string | number)>, RestPaths>
|
|
1875
|
-
: T;
|
|
1876
|
-
|
|
1877
|
-
/**
|
|
1878
|
-
Omit one path from the given object/array.
|
|
1879
|
-
*/
|
|
1880
|
-
type OmitDeepWithOnePath<T, Path extends string | number> =
|
|
1881
|
-
T extends NonRecursiveType
|
|
1882
|
-
? T
|
|
1883
|
-
: T extends UnknownArray ? SetArrayAccess<OmitDeepArrayWithOnePath<T, Path>, IsArrayReadonly<T>>
|
|
1884
|
-
: T extends object ? OmitDeepObjectWithOnePath<T, Path>
|
|
1885
|
-
: T;
|
|
1886
|
-
|
|
1887
|
-
/**
|
|
1888
|
-
Omit one path from the given object.
|
|
1889
|
-
*/
|
|
1890
|
-
type OmitDeepObjectWithOnePath<ObjectT extends object, P extends string | number> =
|
|
1891
|
-
P extends `${infer RecordKeyInPath}.${infer SubPath}`
|
|
1892
|
-
? {
|
|
1893
|
-
[Key in keyof ObjectT]:
|
|
1894
|
-
IsEqual<RecordKeyInPath, ToString<Key>> extends true
|
|
1895
|
-
? ExactKey<ObjectT, Key> extends infer RealKey
|
|
1896
|
-
? RealKey extends keyof ObjectT
|
|
1897
|
-
? OmitDeepWithOnePath<ObjectT[RealKey], SubPath>
|
|
1898
|
-
: ObjectT[Key]
|
|
1899
|
-
: ObjectT[Key]
|
|
1900
|
-
: ObjectT[Key]
|
|
1901
|
-
}
|
|
1902
|
-
: ExactKey<ObjectT, P> extends infer Key
|
|
1903
|
-
? IsNever<Key> extends true
|
|
1904
|
-
? ObjectT
|
|
1905
|
-
: Key extends PropertyKey
|
|
1906
|
-
? Omit<ObjectT, Key>
|
|
1907
|
-
: ObjectT
|
|
1908
|
-
: ObjectT;
|
|
1909
|
-
|
|
1910
|
-
/**
|
|
1911
|
-
Omit one path from from the given array.
|
|
1912
|
-
|
|
1913
|
-
It replaces the item to `unknown` at the given index.
|
|
1914
|
-
|
|
1915
|
-
@example
|
|
1916
|
-
```
|
|
1917
|
-
type A = OmitDeepArrayWithOnePath<[10, 20, 30, 40], 2>;
|
|
1918
|
-
//=> type A = [10, 20, unknown, 40];
|
|
1919
|
-
```
|
|
1920
|
-
*/
|
|
1921
|
-
type OmitDeepArrayWithOnePath<ArrayType extends UnknownArray, P extends string | number> =
|
|
1922
|
-
// Handle paths that are `${number}.${string}`
|
|
1923
|
-
P extends `${infer ArrayIndex extends number}.${infer SubPath}`
|
|
1924
|
-
// If `ArrayIndex` is equal to `number`
|
|
1925
|
-
? number extends ArrayIndex
|
|
1926
|
-
? Array<OmitDeepWithOnePath<NonNullable<ArrayType[number]>, SubPath>>
|
|
1927
|
-
// If `ArrayIndex` is a number literal
|
|
1928
|
-
: ArraySplice<ArrayType, ArrayIndex, 1, [OmitDeepWithOnePath<NonNullable<ArrayType[ArrayIndex]>, SubPath>]>
|
|
1929
|
-
// If the path is equal to `number`
|
|
1930
|
-
: P extends `${infer ArrayIndex extends number}`
|
|
1931
|
-
// If `ArrayIndex` is `number`
|
|
1932
|
-
? number extends ArrayIndex
|
|
1933
|
-
? []
|
|
1934
|
-
// If `ArrayIndex` is a number literal
|
|
1935
|
-
: ArraySplice<ArrayType, ArrayIndex, 1, [unknown]>
|
|
1936
|
-
: ArrayType;
|
|
1937
|
-
|
|
1938
|
-
/**
|
|
1939
|
-
Get keys of the given type as strings.
|
|
1940
|
-
|
|
1941
|
-
Number keys are converted to strings.
|
|
1942
|
-
|
|
1943
|
-
Use-cases:
|
|
1944
|
-
- Get string keys from a type which may have number keys.
|
|
1945
|
-
- Makes it possible to index using strings retrieved from template types.
|
|
1946
|
-
|
|
1947
|
-
@example
|
|
1948
|
-
```
|
|
1949
|
-
import type {StringKeyOf} from 'type-fest';
|
|
1950
|
-
|
|
1951
|
-
type Foo = {
|
|
1952
|
-
1: number,
|
|
1953
|
-
stringKey: string,
|
|
1954
|
-
};
|
|
1955
|
-
|
|
1956
|
-
type StringKeysOfFoo = StringKeyOf<Foo>;
|
|
1957
|
-
//=> '1' | 'stringKey'
|
|
1958
|
-
```
|
|
1959
|
-
|
|
1960
|
-
@category Object
|
|
1961
|
-
*/
|
|
1962
|
-
type StringKeyOf<BaseType> = `${Extract<keyof BaseType, string | number>}`;
|
|
1963
|
-
|
|
1964
|
-
/**
|
|
1965
|
-
Split options.
|
|
1966
|
-
|
|
1967
|
-
@see {@link Split}
|
|
1968
|
-
*/
|
|
1969
|
-
type SplitOptions = {
|
|
1970
|
-
/**
|
|
1971
|
-
When enabled, instantiations with non-literal string types (e.g., `string`, `Uppercase<string>`, `on${string}`) simply return back `string[]` without performing any splitting, as the exact structure cannot be statically determined.
|
|
1972
|
-
|
|
1973
|
-
Note: In the future, this option might be enabled by default, so if you currently rely on this being disabled, you should consider explicitly enabling it.
|
|
1974
|
-
|
|
1975
|
-
@default false
|
|
1976
|
-
|
|
1977
|
-
@example
|
|
1978
|
-
```ts
|
|
1979
|
-
type Example1 = Split<`foo.${string}.bar`, '.', {strictLiteralChecks: false}>;
|
|
1980
|
-
//=> ['foo', string, 'bar']
|
|
1981
|
-
|
|
1982
|
-
type Example2 = Split<`foo.${string}`, '.', {strictLiteralChecks: true}>;
|
|
1983
|
-
//=> string[]
|
|
1984
|
-
|
|
1985
|
-
type Example3 = Split<'foobarbaz', `b${string}`, {strictLiteralChecks: false}>;
|
|
1986
|
-
//=> ['foo', 'r', 'z']
|
|
1987
|
-
|
|
1988
|
-
type Example4 = Split<'foobarbaz', `b${string}`, {strictLiteralChecks: true}>;
|
|
1989
|
-
//=> string[]
|
|
1990
|
-
```
|
|
1991
|
-
*/
|
|
1992
|
-
strictLiteralChecks?: boolean;
|
|
1993
|
-
};
|
|
1994
|
-
|
|
1995
|
-
type DefaultSplitOptions = {
|
|
1996
|
-
strictLiteralChecks: false;
|
|
1997
|
-
};
|
|
1998
|
-
|
|
1999
|
-
/**
|
|
2000
|
-
Represents an array of strings split using a given character or character set.
|
|
2001
|
-
|
|
2002
|
-
Use-case: Defining the return type of a method like `String.prototype.split`.
|
|
2003
|
-
|
|
2004
|
-
@example
|
|
2005
|
-
```
|
|
2006
|
-
import type {Split} from 'type-fest';
|
|
2007
|
-
|
|
2008
|
-
declare function split<S extends string, D extends string>(string: S, separator: D): Split<S, D>;
|
|
2009
|
-
|
|
2010
|
-
type Item = 'foo' | 'bar' | 'baz' | 'waldo';
|
|
2011
|
-
const items = 'foo,bar,baz,waldo';
|
|
2012
|
-
let array: Item[];
|
|
2013
|
-
|
|
2014
|
-
array = split(items, ',');
|
|
2015
|
-
```
|
|
2016
|
-
|
|
2017
|
-
@see {@link SplitOptions}
|
|
2018
|
-
|
|
2019
|
-
@category String
|
|
2020
|
-
@category Template literal
|
|
2021
|
-
*/
|
|
2022
|
-
type Split<
|
|
2023
|
-
S extends string,
|
|
2024
|
-
Delimiter extends string,
|
|
2025
|
-
Options extends SplitOptions = {},
|
|
2026
|
-
> = SplitHelper<S, Delimiter, {
|
|
2027
|
-
strictLiteralChecks: Options['strictLiteralChecks'] extends boolean ? Options['strictLiteralChecks'] : DefaultSplitOptions['strictLiteralChecks'];
|
|
2028
|
-
}>;
|
|
2029
|
-
|
|
2030
|
-
type SplitHelper<
|
|
2031
|
-
S extends string,
|
|
2032
|
-
Delimiter extends string,
|
|
2033
|
-
Options extends Required<SplitOptions>,
|
|
2034
|
-
Accumulator extends string[] = [],
|
|
2035
|
-
> = S extends string // For distributing `S`
|
|
2036
|
-
? Delimiter extends string // For distributing `Delimeter`
|
|
2037
|
-
// If `strictLiteralChecks` is `false` OR `S` and `Delimiter` both are string literals, then perform the split
|
|
2038
|
-
? Or<Not<Options['strictLiteralChecks']>, And<IsStringLiteral<S>, IsStringLiteral<Delimiter>>> extends true
|
|
2039
|
-
? S extends `${infer Head}${Delimiter}${infer Tail}`
|
|
2040
|
-
? SplitHelper<Tail, Delimiter, Options, [...Accumulator, Head]>
|
|
2041
|
-
: Delimiter extends ''
|
|
2042
|
-
? Accumulator
|
|
2043
|
-
: [...Accumulator, S]
|
|
2044
|
-
// Otherwise, return `string[]`
|
|
2045
|
-
: string[]
|
|
2046
|
-
: never // Should never happen
|
|
2047
|
-
: never; // Should never happen
|
|
2048
|
-
|
|
2049
|
-
type GetOptions = {
|
|
2050
|
-
/**
|
|
2051
|
-
Include `undefined` in the return type when accessing properties.
|
|
2052
|
-
|
|
2053
|
-
Setting this to `false` is not recommended.
|
|
2054
|
-
|
|
2055
|
-
@default true
|
|
2056
|
-
*/
|
|
2057
|
-
strict?: boolean;
|
|
2058
|
-
};
|
|
2059
|
-
|
|
2060
|
-
/**
|
|
2061
|
-
Like the `Get` type but receives an array of strings as a path parameter.
|
|
2062
|
-
*/
|
|
2063
|
-
type GetWithPath<BaseType, Keys, Options extends GetOptions = {}> =
|
|
2064
|
-
Keys extends readonly []
|
|
2065
|
-
? BaseType
|
|
2066
|
-
: Keys extends readonly [infer Head, ...infer Tail]
|
|
2067
|
-
? GetWithPath<
|
|
2068
|
-
PropertyOf<BaseType, Extract<Head, string>, Options>,
|
|
2069
|
-
Extract<Tail, string[]>,
|
|
2070
|
-
Options
|
|
2071
|
-
>
|
|
2072
|
-
: never;
|
|
2073
|
-
|
|
2074
|
-
/**
|
|
2075
|
-
Adds `undefined` to `Type` if `strict` is enabled.
|
|
2076
|
-
*/
|
|
2077
|
-
type Strictify<Type, Options extends GetOptions> =
|
|
2078
|
-
Options['strict'] extends false ? Type : (Type | undefined);
|
|
2079
|
-
|
|
2080
|
-
/**
|
|
2081
|
-
If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record<string, any>`.
|
|
2082
|
-
|
|
2083
|
-
Known limitations:
|
|
2084
|
-
- Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`).
|
|
2085
|
-
*/
|
|
2086
|
-
type StrictPropertyOf<BaseType, Key extends keyof BaseType, Options extends GetOptions> =
|
|
2087
|
-
Record<string, any> extends BaseType
|
|
2088
|
-
? string extends keyof BaseType
|
|
2089
|
-
? Strictify<BaseType[Key], Options> // Record<string, any>
|
|
2090
|
-
: BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties)
|
|
2091
|
-
: BaseType[Key];
|
|
2092
|
-
|
|
2093
|
-
/**
|
|
2094
|
-
Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation.
|
|
2095
|
-
|
|
2096
|
-
@example
|
|
2097
|
-
```
|
|
2098
|
-
ToPath<'foo.bar.baz'>
|
|
2099
|
-
//=> ['foo', 'bar', 'baz']
|
|
2100
|
-
|
|
2101
|
-
ToPath<'foo[0].bar.baz'>
|
|
2102
|
-
//=> ['foo', '0', 'bar', 'baz']
|
|
2103
|
-
```
|
|
2104
|
-
*/
|
|
2105
|
-
type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.'>;
|
|
2106
|
-
|
|
2107
|
-
/**
|
|
2108
|
-
Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`.
|
|
2109
|
-
*/
|
|
2110
|
-
type FixPathSquareBrackets<Path extends string> =
|
|
2111
|
-
Path extends `[${infer Head}]${infer Tail}`
|
|
2112
|
-
? Tail extends `[${string}`
|
|
2113
|
-
? `${Head}.${FixPathSquareBrackets<Tail>}`
|
|
2114
|
-
: `${Head}${FixPathSquareBrackets<Tail>}`
|
|
2115
|
-
: Path extends `${infer Head}[${infer Middle}]${infer Tail}`
|
|
2116
|
-
? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}`
|
|
2117
|
-
: Path;
|
|
2118
|
-
|
|
2119
|
-
/**
|
|
2120
|
-
Returns true if `LongString` is made up out of `Substring` repeated 0 or more times.
|
|
2121
|
-
|
|
2122
|
-
@example
|
|
2123
|
-
```
|
|
2124
|
-
ConsistsOnlyOf<'aaa', 'a'> //=> true
|
|
2125
|
-
ConsistsOnlyOf<'ababab', 'ab'> //=> true
|
|
2126
|
-
ConsistsOnlyOf<'aBa', 'a'> //=> false
|
|
2127
|
-
ConsistsOnlyOf<'', 'a'> //=> true
|
|
2128
|
-
```
|
|
2129
|
-
*/
|
|
2130
|
-
type ConsistsOnlyOf<LongString extends string, Substring extends string> =
|
|
2131
|
-
LongString extends ''
|
|
2132
|
-
? true
|
|
2133
|
-
: LongString extends `${Substring}${infer Tail}`
|
|
2134
|
-
? ConsistsOnlyOf<Tail, Substring>
|
|
2135
|
-
: false;
|
|
2136
|
-
|
|
2137
|
-
/**
|
|
2138
|
-
Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types.
|
|
2139
|
-
|
|
2140
|
-
@example
|
|
2141
|
-
```
|
|
2142
|
-
type WithNumbers = {foo: string; 0: boolean};
|
|
2143
|
-
type WithStrings = WithStringKeys<WithNumbers>;
|
|
2144
|
-
|
|
2145
|
-
type WithNumbersKeys = keyof WithNumbers;
|
|
2146
|
-
//=> 'foo' | 0
|
|
2147
|
-
type WithStringsKeys = keyof WithStrings;
|
|
2148
|
-
//=> 'foo' | '0'
|
|
2149
|
-
```
|
|
2150
|
-
*/
|
|
2151
|
-
type WithStringKeys<BaseType> = {
|
|
2152
|
-
[Key in StringKeyOf<BaseType>]: UncheckedIndex<BaseType, Key>
|
|
2153
|
-
};
|
|
2154
|
-
|
|
2155
|
-
/**
|
|
2156
|
-
Perform a `T[U]` operation if `T` supports indexing.
|
|
2157
|
-
*/
|
|
2158
|
-
type UncheckedIndex<T, U extends string | number> = [T] extends [Record<string | number, any>] ? T[U] : never;
|
|
2159
|
-
|
|
2160
|
-
/**
|
|
2161
|
-
Get a property of an object or array. Works when indexing arrays using number-literal-strings, for example, `PropertyOf<number[], '0'> = number`, and when indexing objects with number keys.
|
|
2162
|
-
|
|
2163
|
-
Note:
|
|
2164
|
-
- Returns `unknown` if `Key` is not a property of `BaseType`, since TypeScript uses structural typing, and it cannot be guaranteed that extra properties unknown to the type system will exist at runtime.
|
|
2165
|
-
- Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc.
|
|
2166
|
-
*/
|
|
2167
|
-
type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
|
|
2168
|
-
BaseType extends null | undefined
|
|
2169
|
-
? undefined
|
|
2170
|
-
: Key extends keyof BaseType
|
|
2171
|
-
? StrictPropertyOf<BaseType, Key, Options>
|
|
2172
|
-
// Handle arrays and tuples
|
|
2173
|
-
: BaseType extends readonly unknown[]
|
|
2174
|
-
? Key extends `${number}`
|
|
2175
|
-
// For arrays with unknown length (regular arrays)
|
|
2176
|
-
? number extends BaseType['length']
|
|
2177
|
-
? Strictify<BaseType[number], Options>
|
|
2178
|
-
// For tuples: check if the index is valid
|
|
2179
|
-
: Key extends keyof BaseType
|
|
2180
|
-
? Strictify<BaseType[Key & keyof BaseType], Options>
|
|
2181
|
-
// Out-of-bounds access for tuples
|
|
2182
|
-
: unknown
|
|
2183
|
-
// Non-numeric string key for arrays/tuples
|
|
2184
|
-
: unknown
|
|
2185
|
-
// Handle array-like objects
|
|
2186
|
-
: BaseType extends {
|
|
2187
|
-
[n: number]: infer Item;
|
|
2188
|
-
length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
|
|
2189
|
-
}
|
|
2190
|
-
? (
|
|
2191
|
-
ConsistsOnlyOf<Key, StringDigit> extends true
|
|
2192
|
-
? Strictify<Item, Options>
|
|
2193
|
-
: unknown
|
|
2194
|
-
)
|
|
2195
|
-
: Key extends keyof WithStringKeys<BaseType>
|
|
2196
|
-
? StrictPropertyOf<WithStringKeys<BaseType>, Key, Options>
|
|
2197
|
-
: unknown;
|
|
2198
|
-
|
|
2199
|
-
// This works by first splitting the path based on `.` and `[...]` characters into a tuple of string keys. Then it recursively uses the head key to get the next property of the current object, until there are no keys left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples and dictionaries with number keys.
|
|
2200
|
-
/**
|
|
2201
|
-
Get a deeply-nested property from an object using a key path, like Lodash's `.get()` function.
|
|
2202
|
-
|
|
2203
|
-
Use-case: Retrieve a property from deep inside an API response or some other complex object.
|
|
2204
|
-
|
|
2205
|
-
@example
|
|
2206
|
-
```
|
|
2207
|
-
import type {Get} from 'type-fest';
|
|
2208
|
-
import * as lodash from 'lodash';
|
|
2209
|
-
|
|
2210
|
-
const get = <BaseType, Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path> =>
|
|
2211
|
-
lodash.get(object, path);
|
|
2212
|
-
|
|
2213
|
-
interface ApiResponse {
|
|
2214
|
-
hits: {
|
|
2215
|
-
hits: Array<{
|
|
2216
|
-
_id: string
|
|
2217
|
-
_source: {
|
|
2218
|
-
name: Array<{
|
|
2219
|
-
given: string[]
|
|
2220
|
-
family: string
|
|
2221
|
-
}>
|
|
2222
|
-
birthDate: string
|
|
2223
|
-
}
|
|
2224
|
-
}>
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
|
|
2228
|
-
const getName = (apiResponse: ApiResponse) =>
|
|
2229
|
-
get(apiResponse, 'hits.hits[0]._source.name');
|
|
2230
|
-
//=> Array<{given: string[]; family: string}> | undefined
|
|
2231
|
-
|
|
2232
|
-
// Path also supports a readonly array of strings
|
|
2233
|
-
const getNameWithPathArray = (apiResponse: ApiResponse) =>
|
|
2234
|
-
get(apiResponse, ['hits','hits', '0', '_source', 'name'] as const);
|
|
2235
|
-
//=> Array<{given: string[]; family: string}> | undefined
|
|
2236
|
-
|
|
2237
|
-
// Non-strict mode:
|
|
2238
|
-
Get<string[], '3', {strict: false}> //=> string
|
|
2239
|
-
Get<Record<string, string>, 'foo', {strict: true}> // => string
|
|
2240
|
-
```
|
|
2241
|
-
|
|
2242
|
-
@category Object
|
|
2243
|
-
@category Array
|
|
2244
|
-
@category Template literal
|
|
2245
|
-
*/
|
|
2246
|
-
type Get<
|
|
2247
|
-
BaseType,
|
|
2248
|
-
Path extends
|
|
2249
|
-
| readonly string[]
|
|
2250
|
-
| LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
|
|
2251
|
-
Options extends GetOptions = {}> =
|
|
2252
|
-
GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
|
|
2253
|
-
|
|
2254
|
-
declare const omit: <T extends { [key in string]: unknown; }, K extends string>(object: T, keys: Paths<T>[]) => OmitDeep<T, K>;
|
|
2255
|
-
|
|
2256
|
-
declare const pick: <T extends { [key in string]: unknown; }, K extends Paths<T>>(object: T, keys: Paths<T>[]) => PickDeep<T, K>;
|
|
2257
|
-
|
|
2258
|
-
interface DeeksOptions {
|
|
2259
|
-
/** @default false */
|
|
2260
|
-
arrayIndexesAsKeys?: boolean;
|
|
2261
|
-
/** @default true */
|
|
2262
|
-
expandNestedObjects?: boolean;
|
|
2263
|
-
/** @default false */
|
|
2264
|
-
expandArrayObjects?: boolean;
|
|
2265
|
-
/** @default false */
|
|
2266
|
-
ignoreEmptyArraysWhenExpanding?: boolean;
|
|
2267
|
-
/** @default false */
|
|
2268
|
-
escapeNestedDots?: boolean;
|
|
2269
|
-
/** @default false */
|
|
2270
|
-
ignoreEmptyArrays?: boolean;
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
/**
|
|
2274
|
-
* Return the deep keys list for a single document
|
|
2275
|
-
* @param object
|
|
2276
|
-
* @param options
|
|
2277
|
-
* @returns {Array}
|
|
2278
|
-
*/
|
|
2279
|
-
declare function deepKeys(object: object, options?: DeeksOptions): string[];
|
|
2280
|
-
/**
|
|
2281
|
-
* Return the deep keys list for all documents in the provided list
|
|
2282
|
-
* @param list
|
|
2283
|
-
* @param options
|
|
2284
|
-
* @returns Array[Array[String]]
|
|
2285
|
-
*/
|
|
2286
|
-
declare function deepKeysFromList(list: object[], options?: DeeksOptions): string[][];
|
|
2287
|
-
|
|
2288
|
-
/**
|
|
2289
|
-
Get the value of the property at the given path.
|
|
2290
|
-
|
|
2291
|
-
@param object - Object or array to get the `path` value.
|
|
2292
|
-
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
|
|
2293
|
-
@param defaultValue - Default value.
|
|
2294
|
-
|
|
2295
|
-
@example
|
|
2296
|
-
```
|
|
2297
|
-
import {getProperty} from 'dot-prop';
|
|
2298
|
-
|
|
2299
|
-
getProperty({foo: {bar: 'unicorn'}}, 'foo.bar');
|
|
2300
|
-
//=> 'unicorn'
|
|
2301
|
-
|
|
2302
|
-
getProperty({foo: {bar: 'a'}}, 'foo.notDefined.deep');
|
|
2303
|
-
//=> undefined
|
|
2304
|
-
|
|
2305
|
-
getProperty({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value');
|
|
2306
|
-
//=> 'default value'
|
|
2307
|
-
|
|
2308
|
-
getProperty({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot');
|
|
2309
|
-
//=> 'unicorn'
|
|
2310
|
-
|
|
2311
|
-
getProperty({foo: [{bar: 'unicorn'}]}, 'foo[0].bar');
|
|
2312
|
-
//=> 'unicorn'
|
|
2313
|
-
```
|
|
2314
|
-
*/
|
|
2315
|
-
declare function getProperty<ObjectType, PathType extends string, DefaultValue = undefined>(
|
|
2316
|
-
object: ObjectType,
|
|
2317
|
-
path: PathType,
|
|
2318
|
-
defaultValue?: DefaultValue
|
|
2319
|
-
): ObjectType extends Record<string, unknown> | unknown[] ? (unknown extends Get<ObjectType, PathType> ? DefaultValue : Get<ObjectType, PathType>) : undefined;
|
|
2320
|
-
|
|
2321
|
-
/**
|
|
2322
|
-
Set the property at the given path to the given value.
|
|
2323
|
-
|
|
2324
|
-
@param object - Object or array to set the `path` value.
|
|
2325
|
-
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
|
|
2326
|
-
@param value - Value to set at `path`.
|
|
2327
|
-
@returns The object.
|
|
2328
|
-
|
|
2329
|
-
@example
|
|
2330
|
-
```
|
|
2331
|
-
import {setProperty} from 'dot-prop';
|
|
2332
|
-
|
|
2333
|
-
const object = {foo: {bar: 'a'}};
|
|
2334
|
-
setProperty(object, 'foo.bar', 'b');
|
|
2335
|
-
console.log(object);
|
|
2336
|
-
//=> {foo: {bar: 'b'}}
|
|
2337
|
-
|
|
2338
|
-
const foo = setProperty({}, 'foo.bar', 'c');
|
|
2339
|
-
console.log(foo);
|
|
2340
|
-
//=> {foo: {bar: 'c'}}
|
|
2341
|
-
|
|
2342
|
-
setProperty(object, 'foo.baz', 'x');
|
|
2343
|
-
console.log(object);
|
|
2344
|
-
//=> {foo: {bar: 'b', baz: 'x'}}
|
|
2345
|
-
|
|
2346
|
-
setProperty(object, 'foo.biz[0]', 'a');
|
|
2347
|
-
console.log(object);
|
|
2348
|
-
//=> {foo: {bar: 'b', baz: 'x', biz: ['a']}}
|
|
2349
|
-
```
|
|
2350
|
-
*/
|
|
2351
|
-
declare function setProperty<ObjectType extends Record<string, any>>(
|
|
2352
|
-
object: ObjectType,
|
|
2353
|
-
path: string,
|
|
2354
|
-
value: unknown
|
|
2355
|
-
): ObjectType;
|
|
2356
|
-
|
|
2357
|
-
/**
|
|
2358
|
-
Check whether the property at the given path exists.
|
|
2359
|
-
|
|
2360
|
-
@param object - Object or array to test the `path` value.
|
|
2361
|
-
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
|
|
2362
|
-
|
|
2363
|
-
@example
|
|
2364
|
-
```
|
|
2365
|
-
import {hasProperty} from 'dot-prop';
|
|
2366
|
-
|
|
2367
|
-
hasProperty({foo: {bar: 'unicorn'}}, 'foo.bar');
|
|
2368
|
-
//=> true
|
|
2369
|
-
```
|
|
2370
|
-
*/
|
|
2371
|
-
declare function hasProperty(object: Record<string, any> | undefined, path: string): boolean;
|
|
2372
|
-
|
|
2373
|
-
/**
|
|
2374
|
-
Delete the property at the given path.
|
|
2375
|
-
|
|
2376
|
-
@param object - Object or array to delete the `path` value.
|
|
2377
|
-
@param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
|
|
2378
|
-
@returns A boolean of whether the property existed before being deleted.
|
|
2379
|
-
|
|
2380
|
-
@example
|
|
2381
|
-
```
|
|
2382
|
-
import {deleteProperty} from 'dot-prop';
|
|
2383
|
-
|
|
2384
|
-
const object = {foo: {bar: 'a'}};
|
|
2385
|
-
deleteProperty(object, 'foo.bar');
|
|
2386
|
-
console.log(object);
|
|
2387
|
-
//=> {foo: {}}
|
|
2388
|
-
|
|
2389
|
-
object.foo.bar = {x: 'y', y: 'x'};
|
|
2390
|
-
deleteProperty(object, 'foo.bar.x');
|
|
2391
|
-
console.log(object);
|
|
2392
|
-
//=> {foo: {bar: {y: 'x'}}}
|
|
2393
|
-
```
|
|
2394
|
-
*/
|
|
2395
|
-
declare function deleteProperty(object: Record<string, any>, path: string): boolean;
|
|
2396
|
-
|
|
2397
|
-
/**
|
|
2398
|
-
Escape special characters in a path. Useful for sanitizing user input.
|
|
2399
|
-
|
|
2400
|
-
@param path - The dot path to sanitize.
|
|
2401
|
-
|
|
2402
|
-
@example
|
|
2403
|
-
```
|
|
2404
|
-
import {getProperty, escapePath} from 'dot-prop';
|
|
2405
|
-
|
|
2406
|
-
const object = {
|
|
2407
|
-
foo: {
|
|
2408
|
-
bar: 'πΈπ» You found me Mario!',
|
|
2409
|
-
},
|
|
2410
|
-
'foo.bar' : 'π The princess is in another castle!',
|
|
2411
|
-
};
|
|
2412
|
-
const escapedPath = escapePath('foo.bar');
|
|
2413
|
-
|
|
2414
|
-
console.log(getProperty(object, escapedPath));
|
|
2415
|
-
//=> 'π The princess is in another castle!'
|
|
2416
|
-
```
|
|
2417
|
-
*/
|
|
2418
|
-
declare function escapePath(path: string): string;
|
|
2419
|
-
|
|
2420
|
-
/**
|
|
2421
|
-
Check if a value is a plain object.
|
|
2422
|
-
|
|
2423
|
-
An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`.
|
|
2424
|
-
|
|
2425
|
-
@example
|
|
2426
|
-
```
|
|
2427
|
-
import isPlainObject from 'is-plain-obj';
|
|
2428
|
-
import {runInNewContext} from 'node:vm';
|
|
2429
|
-
|
|
2430
|
-
isPlainObject({foo: 'bar'});
|
|
2431
|
-
//=> true
|
|
2432
|
-
|
|
2433
|
-
isPlainObject(new Object());
|
|
2434
|
-
//=> true
|
|
2435
|
-
|
|
2436
|
-
isPlainObject(Object.create(null));
|
|
2437
|
-
//=> true
|
|
2438
|
-
|
|
2439
|
-
// This works across realms
|
|
2440
|
-
isPlainObject(runInNewContext('({})'));
|
|
2441
|
-
//=> true
|
|
2442
|
-
|
|
2443
|
-
isPlainObject([1, 2, 3]);
|
|
2444
|
-
//=> false
|
|
2445
|
-
|
|
2446
|
-
class Unicorn {}
|
|
2447
|
-
isPlainObject(new Unicorn());
|
|
2448
|
-
//=> false
|
|
2449
|
-
|
|
2450
|
-
isPlainObject(Math);
|
|
2451
|
-
//=> false
|
|
2452
|
-
```
|
|
2453
|
-
*/
|
|
2454
|
-
declare function isPlainObject<Value>(value: unknown): value is Record<PropertyKey, Value>;
|
|
2455
|
-
|
|
2456
|
-
export { type DeeksOptions as DeepKeysOptions, type OmitDeep, type Paths, type PickDeep, type Split, deepKeys, deepKeysFromList, deleteProperty, escapePath, getProperty, hasProperty, isPlainObject, omit, pick, setProperty };
|
|
1
|
+
export { default as omit } from "./omit.d.cts";
|
|
2
|
+
export { default as pick } from "./pick.d.cts";
|
|
3
|
+
export type { DeeksOptions as DeepKeysOptions } from "deeks";
|
|
4
|
+
export { deepKeys, deepKeysFromList } from "deeks";
|
|
5
|
+
export { deleteProperty, escapePath, getProperty, hasProperty, setProperty } from "dot-prop";
|
|
6
|
+
export { default as isPlainObject } from "is-plain-obj";
|
|
7
|
+
export type { OmitDeep, Paths, PickDeep, Split } from "type-fest";
|