@visulima/object 1.0.10 β†’ 1.0.12

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/dist/index.d.cts CHANGED
@@ -1,2456 +1,7 @@
1
- /**
2
- Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
3
-
4
- @category Type
5
- */
6
- type Primitive =
7
- | null
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 ".//index.d.d.cts";