type-fest 4.20.1 → 4.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,783 +0,0 @@
1
- import type {Primitive} from './primitive';
2
- import type {Simplify} from './simplify';
3
- import type {Trim} from './trim';
4
- import type {IsAny} from './is-any';
5
- import type {NegativeInfinity, PositiveInfinity} from './numeric';
6
- import type {GreaterThan} from './greater-than';
7
- import type {LessThan} from './less-than';
8
- import type {IsLiteral} from './is-literal';
9
- import type {UnknownRecord} from './unknown-record';
10
- import type {IsNever} from './is-never';
11
- import type {UnknownArray} from './unknown-array';
12
- import type {IsEqual} from './is-equal';
13
-
14
- // TODO: Remove for v5.
15
- export type {UnknownRecord} from './unknown-record';
16
-
17
- /**
18
- Infer the length of the given array `<T>`.
19
-
20
- @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
21
- */
22
- type ArrayLength<T extends readonly unknown[]> = T extends {readonly length: infer L} ? L : never;
23
-
24
- /**
25
- Infer the length of the given tuple `<T>`.
26
-
27
- Returns `never` if the given type is an non-fixed-length array like `Array<string>`.
28
-
29
- @example
30
- ```
31
- type Tuple = TupleLength<[string, number, boolean]>;
32
- //=> 3
33
-
34
- type Array = TupleLength<string[]>;
35
- //=> never
36
-
37
- // Supports union types.
38
- type Union = TupleLength<[] | [1, 2, 3] | Array<number>>;
39
- //=> 1 | 3
40
- ```
41
- */
42
- export type TupleLength<T extends UnknownArray> =
43
- // `extends unknown` is used to convert `T` (if `T` is a union type) to
44
- // a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types))
45
- T extends unknown
46
- ? number extends T['length']
47
- ? never // Return never if the given type is an non-flexed-length array like `Array<string>`
48
- : T['length']
49
- : never; // Should never happen
50
-
51
- /**
52
- Create a tuple type of the given length `<L>` and fill it with the given type `<Fill>`.
53
-
54
- If `<Fill>` is not provided, it will default to `unknown`.
55
-
56
- @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
57
- */
58
- export type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = T['length'] extends L
59
- ? T
60
- : BuildTuple<L, Fill, [...T, Fill]>;
61
-
62
- /**
63
- Create an object type with the given key `<Key>` and value `<Value>`.
64
-
65
- It will copy the prefix and optional status of the same key from the given object `CopiedFrom` into the result.
66
-
67
- @example
68
- ```
69
- type A = BuildObject<'a', string>;
70
- //=> {a: string}
71
-
72
- // Copy `readonly` and `?` from the key `a` of `{readonly a?: any}`
73
- type B = BuildObject<'a', string, {readonly a?: any}>;
74
- //=> {readonly a?: string}
75
- ```
76
- */
77
- export type BuildObject<Key extends PropertyKey, Value, CopiedFrom extends object = {}> =
78
- Key extends keyof CopiedFrom
79
- ? Pick<{[_ in keyof CopiedFrom]: Value}, Key>
80
- : Key extends `${infer NumberKey extends number}`
81
- ? NumberKey extends keyof CopiedFrom
82
- ? Pick<{[_ in keyof CopiedFrom]: Value}, NumberKey>
83
- : {[_ in Key]: Value}
84
- : {[_ in Key]: Value};
85
-
86
- /**
87
- Return a string representation of the given string or number.
88
-
89
- Note: This type is not the return type of the `.toString()` function.
90
- */
91
- export type ToString<T> = T extends string | number ? `${T}` : never;
92
-
93
- /**
94
- Matches any primitive, `void`, `Date`, or `RegExp` value.
95
- */
96
- export type BuiltIns = Primitive | void | Date | RegExp;
97
-
98
- /**
99
- Matches non-recursive types.
100
- */
101
- export type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
102
-
103
- /**
104
- Returns a boolean for whether the given type is a plain key-value object.
105
- */
106
- export type IsPlainObject<T> =
107
- T extends NonRecursiveType | UnknownArray | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
108
- ? false
109
- : T extends object
110
- ? true
111
- : false;
112
-
113
- /**
114
- Converts a numeric string to a number.
115
-
116
- @example
117
- ```
118
- type PositiveInt = StringToNumber<'1234'>;
119
- //=> 1234
120
-
121
- type NegativeInt = StringToNumber<'-1234'>;
122
- //=> -1234
123
-
124
- type PositiveFloat = StringToNumber<'1234.56'>;
125
- //=> 1234.56
126
-
127
- type NegativeFloat = StringToNumber<'-1234.56'>;
128
- //=> -1234.56
129
-
130
- type PositiveInfinity = StringToNumber<'Infinity'>;
131
- //=> Infinity
132
-
133
- type NegativeInfinity = StringToNumber<'-Infinity'>;
134
- //=> -Infinity
135
- ```
136
-
137
- @category String
138
- @category Numeric
139
- @category Template literal
140
- */
141
- export type StringToNumber<S extends string> = S extends `${infer N extends number}`
142
- ? N
143
- : S extends 'Infinity'
144
- ? PositiveInfinity
145
- : S extends '-Infinity'
146
- ? NegativeInfinity
147
- : never;
148
-
149
- /**
150
- Returns a boolean for whether the given string `S` starts with the given string `SearchString`.
151
-
152
- @example
153
- ```
154
- StartsWith<'abcde', 'abc'>;
155
- //=> true
156
-
157
- StartsWith<'abcde', 'bc'>;
158
- //=> false
159
-
160
- StartsWith<string, 'bc'>;
161
- //=> never
162
-
163
- StartsWith<'abcde', string>;
164
- //=> never
165
- ```
166
-
167
- @category String
168
- @category Template literal
169
- */
170
- export type StartsWith<S extends string, SearchString extends string> = string extends S | SearchString
171
- ? never
172
- : S extends `${SearchString}${infer T}`
173
- ? true
174
- : false;
175
-
176
- /**
177
- Returns the length of the given string.
178
-
179
- @example
180
- ```
181
- StringLength<'abcde'>;
182
- //=> 5
183
-
184
- StringLength<string>;
185
- //=> never
186
- ```
187
-
188
- @category String
189
- @category Template literal
190
- */
191
- export type StringLength<S extends string> = string extends S
192
- ? never
193
- : StringToArray<S>['length'];
194
-
195
- /**
196
- Returns an array of the characters of the string.
197
-
198
- @example
199
- ```
200
- StringToArray<'abcde'>;
201
- //=> ['a', 'b', 'c', 'd', 'e']
202
-
203
- StringToArray<string>;
204
- //=> never
205
- ```
206
-
207
- @category String
208
- */
209
- export type StringToArray<S extends string, Result extends string[] = []> = string extends S
210
- ? never
211
- : S extends `${infer F}${infer R}`
212
- ? StringToArray<R, [...Result, F]>
213
- : Result;
214
-
215
- export type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
216
-
217
- export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
218
-
219
- export type Whitespace =
220
- | '\u{9}' // '\t'
221
- | '\u{A}' // '\n'
222
- | '\u{B}' // '\v'
223
- | '\u{C}' // '\f'
224
- | '\u{D}' // '\r'
225
- | '\u{20}' // ' '
226
- | '\u{85}'
227
- | '\u{A0}'
228
- | '\u{1680}'
229
- | '\u{2000}'
230
- | '\u{2001}'
231
- | '\u{2002}'
232
- | '\u{2003}'
233
- | '\u{2004}'
234
- | '\u{2005}'
235
- | '\u{2006}'
236
- | '\u{2007}'
237
- | '\u{2008}'
238
- | '\u{2009}'
239
- | '\u{200A}'
240
- | '\u{2028}'
241
- | '\u{2029}'
242
- | '\u{202F}'
243
- | '\u{205F}'
244
- | '\u{3000}'
245
- | '\u{FEFF}';
246
-
247
- export type WordSeparators = '-' | '_' | Whitespace;
248
-
249
- /**
250
- Matches any unknown array or tuple.
251
- */
252
- export type UnknownArrayOrTuple = readonly [...unknown[]];
253
-
254
- /**
255
- Matches any non empty tuple.
256
- */
257
- export type NonEmptyTuple = readonly [unknown, ...unknown[]];
258
-
259
- /**
260
- Returns a boolean for whether the two given types extends the base type.
261
- */
262
- export type IsBothExtends<BaseType, FirstType, SecondType> = FirstType extends BaseType
263
- ? SecondType extends BaseType
264
- ? true
265
- : false
266
- : false;
267
-
268
- /**
269
- Extracts the type of the first element of an array or tuple.
270
- */
271
- export type FirstArrayElement<TArray extends UnknownArrayOrTuple> = TArray extends readonly [infer THead, ...unknown[]]
272
- ? THead
273
- : never;
274
-
275
- /**
276
- Extracts the type of an array or tuple minus the first element.
277
- */
278
- export type ArrayTail<TArray extends UnknownArrayOrTuple> = TArray extends readonly [unknown, ...infer TTail] ? TTail : [];
279
-
280
- /**
281
- Extract the element of an array that also works for array union.
282
-
283
- Returns `never` if T is not an array.
284
-
285
- It creates a type-safe way to access the element type of `unknown` type.
286
- */
287
- export type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
288
-
289
- /**
290
- Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
291
-
292
- It creates a type-safe way to access the member type of `unknown` type.
293
- */
294
- export type ObjectValue<T, K> =
295
- K extends keyof T
296
- ? T[K]
297
- : ToString<K> extends keyof T
298
- ? T[ToString<K>]
299
- : K extends `${infer NumberK extends number}`
300
- ? NumberK extends keyof T
301
- ? T[NumberK]
302
- : never
303
- : never;
304
-
305
- /**
306
- Returns a boolean for whether the string is lowercased.
307
- */
308
- export type IsLowerCase<T extends string> = T extends Lowercase<T> ? true : false;
309
-
310
- /**
311
- Returns a boolean for whether the string is uppercased.
312
- */
313
- export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : false;
314
-
315
- /**
316
- Returns a boolean for whether a string is whitespace.
317
- */
318
- export type IsWhitespace<T extends string> = T extends Whitespace
319
- ? true
320
- : T extends `${Whitespace}${infer Rest}`
321
- ? IsWhitespace<Rest>
322
- : false;
323
-
324
- /**
325
- Returns a boolean for whether the string is numeric.
326
-
327
- This type is a workaround for [Microsoft/TypeScript#46109](https://github.com/microsoft/TypeScript/issues/46109#issuecomment-930307987).
328
- */
329
- export type IsNumeric<T extends string> = T extends `${number}`
330
- ? Trim<T> extends T
331
- ? true
332
- : false
333
- : false;
334
-
335
- /**
336
- For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead.
337
-
338
- @example
339
- ```
340
- type User = {
341
- firstName: string;
342
- lastName: string | undefined;
343
- };
344
-
345
- type OptionalizedUser = UndefinedToOptional<User>;
346
- //=> {
347
- // firstName: string;
348
- // lastName?: string;
349
- // }
350
- ```
351
- */
352
- export type UndefinedToOptional<T extends object> = Simplify<
353
- {
354
- // Property is not a union with `undefined`, keep it as-is.
355
- [Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key];
356
- } & {
357
- // Property _is_ a union with defined value. Set as optional (via `?`) and remove `undefined` from the union.
358
- [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
359
- }
360
- >;
361
-
362
- // Returns `never` if the key or property is not jsonable without testing whether the property is required or optional otherwise return the key.
363
- type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
364
- ? never
365
- : Type[Key] extends symbol
366
- ? never
367
- /*
368
- To prevent a problem where an object with only a `name` property is incorrectly treated as assignable to a function, we first check if the property is a record.
369
- This check is necessary, because without it, if we don't verify whether the property is a record, an object with a type of `{name: any}` would return `never` due to its potential assignability to a function.
370
- See: https://github.com/sindresorhus/type-fest/issues/657
371
- */
372
- : Type[Key] extends Record<string, unknown>
373
- ? Key
374
- : [(...arguments_: any[]) => any] extends [Type[Key]]
375
- ? never
376
- : Key;
377
-
378
- /**
379
- Returns the required keys.
380
- */
381
- type FilterDefinedKeys<T extends object> = Exclude<
382
- {
383
- [Key in keyof T]: IsAny<T[Key]> extends true
384
- ? Key
385
- : undefined extends T[Key]
386
- ? never
387
- : T[Key] extends undefined
388
- ? never
389
- : BaseKeyFilter<T, Key>;
390
- }[keyof T],
391
- undefined
392
- >;
393
-
394
- /**
395
- Returns the optional keys.
396
- */
397
- type FilterOptionalKeys<T extends object> = Exclude<
398
- {
399
- [Key in keyof T]: IsAny<T[Key]> extends true
400
- ? never
401
- : undefined extends T[Key]
402
- ? T[Key] extends undefined
403
- ? never
404
- : BaseKeyFilter<T, Key>
405
- : never;
406
- }[keyof T],
407
- undefined
408
- >;
409
-
410
- /**
411
- Test if the given function has multiple call signatures.
412
-
413
- Needed to handle the case of a single call signature with properties.
414
-
415
- Multiple call signatures cannot currently be supported due to a TypeScript limitation.
416
- @see https://github.com/microsoft/TypeScript/issues/29732
417
- */
418
- export type HasMultipleCallSignatures<T extends (...arguments_: any[]) => unknown> =
419
- T extends {(...arguments_: infer A): unknown; (...arguments_: infer B): unknown}
420
- ? B extends A
421
- ? A extends B
422
- ? false
423
- : true
424
- : true
425
- : false;
426
-
427
- /**
428
- Returns a boolean for whether the given `boolean` is not `false`.
429
- */
430
- export type IsNotFalse<T extends boolean> = [T] extends [false] ? false : true;
431
-
432
- /**
433
- Disallows any of the given keys.
434
- */
435
- export type RequireNone<KeysType extends PropertyKey> = Partial<Record<KeysType, never>>;
436
-
437
- /**
438
- Returns a boolean for whether the given type is primitive value or primitive type.
439
-
440
- @example
441
- ```
442
- IsPrimitive<'string'>
443
- //=> true
444
-
445
- IsPrimitive<string>
446
- //=> true
447
-
448
- IsPrimitive<Object>
449
- //=> false
450
- ```
451
- */
452
- export type IsPrimitive<T> = [T] extends [Primitive] ? true : false;
453
-
454
- /**
455
- Returns a boolean for whether A is false.
456
-
457
- @example
458
- ```
459
- Not<true>;
460
- //=> false
461
-
462
- Not<false>;
463
- //=> true
464
- ```
465
- */
466
- export type Not<A extends boolean> = A extends true
467
- ? false
468
- : A extends false
469
- ? true
470
- : never;
471
-
472
- /**
473
- Returns the maximum value from a tuple of integers.
474
-
475
- Note:
476
- - Float numbers are not supported.
477
-
478
- @example
479
- ```
480
- ArrayMax<[1, 2, 5, 3]>;
481
- //=> 5
482
-
483
- ArrayMax<[1, 2, 5, 3, 99, -1]>;
484
- //=> 99
485
- ```
486
- */
487
- export type ArrayMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
488
- ? never :
489
- A extends [infer F extends number, ...infer R extends number[]]
490
- ? GreaterThan<F, Result> extends true
491
- ? ArrayMax<R, F>
492
- : ArrayMax<R, Result>
493
- : Result;
494
-
495
- /**
496
- Returns the minimum value from a tuple of integers.
497
-
498
- Note:
499
- - Float numbers are not supported.
500
-
501
- @example
502
- ```
503
- ArrayMin<[1, 2, 5, 3]>;
504
- //=> 1
505
-
506
- ArrayMin<[1, 2, 5, 3, -5]>;
507
- //=> -5
508
- ```
509
- */
510
- export type ArrayMin<A extends number[], Result extends number = PositiveInfinity> = number extends A[number]
511
- ? never
512
- : A extends [infer F extends number, ...infer R extends number[]]
513
- ? LessThan<F, Result> extends true
514
- ? ArrayMin<R, F>
515
- : ArrayMin<R, Result>
516
- : Result;
517
-
518
- /**
519
- Returns the absolute value of a given value.
520
-
521
- @example
522
- ```
523
- NumberAbsolute<-1>;
524
- //=> 1
525
-
526
- NumberAbsolute<1>;
527
- //=> 1
528
-
529
- NumberAbsolute<NegativeInfinity>
530
- //=> PositiveInfinity
531
- ```
532
- */
533
- export type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
534
-
535
- /**
536
- 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.
537
-
538
- @example
539
- ```
540
- SameLengthPositiveNumericStringGt<'50', '10'>;
541
- //=> true
542
-
543
- SameLengthPositiveNumericStringGt<'10', '10'>;
544
- //=> false
545
- ```
546
- */
547
- type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}`
548
- ? B extends `${infer FirstB}${infer RestB}`
549
- ? FirstA extends FirstB
550
- ? SameLengthPositiveNumericStringGt<RestA, RestB>
551
- : PositiveNumericCharacterGt<FirstA, FirstB>
552
- : never
553
- : false;
554
-
555
- type NumericString = '0123456789';
556
-
557
- /**
558
- Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
559
-
560
- @example
561
- ```
562
- PositiveNumericStringGt<'500', '1'>;
563
- //=> true
564
-
565
- PositiveNumericStringGt<'1', '1'>;
566
- //=> false
567
-
568
- PositiveNumericStringGt<'1', '500'>;
569
- //=> false
570
- ```
571
- */
572
- export type PositiveNumericStringGt<A extends string, B extends string> = A extends B
573
- ? false
574
- : [BuildTuple<StringLength<A>, 0>, BuildTuple<StringLength<B>, 0>] extends infer R extends [readonly unknown[], readonly unknown[]]
575
- ? R[0] extends [...R[1], ...infer Remain extends readonly unknown[]]
576
- ? 0 extends Remain['length']
577
- ? SameLengthPositiveNumericStringGt<A, B>
578
- : true
579
- : false
580
- : never;
581
-
582
- /**
583
- Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both positive numeric characters.
584
-
585
- @example
586
- ```
587
- PositiveNumericCharacterGt<'5', '1'>;
588
- //=> true
589
-
590
- PositiveNumericCharacterGt<'1', '1'>;
591
- //=> false
592
- ```
593
- */
594
- type PositiveNumericCharacterGt<A extends string, B extends string> = NumericString extends `${infer HeadA}${A}${infer TailA}`
595
- ? NumericString extends `${infer HeadB}${B}${infer TailB}`
596
- ? HeadA extends `${HeadB}${infer _}${infer __}`
597
- ? true
598
- : false
599
- : never
600
- : never;
601
-
602
- /**
603
- Utility type to retrieve only literal keys from type.
604
- */
605
- export type LiteralKeyOf<T> = keyof {[K in keyof T as IsLiteral<K> extends true ? K : never]-?: never};
606
-
607
- /**
608
- Returns the static, fixed-length portion of the given array, excluding variable-length parts.
609
-
610
- @example
611
- ```
612
- type A = [string, number, boolean, ...string[]];
613
- type B = StaticPartOfArray<A>;
614
- //=> [string, number, boolean]
615
- ```
616
- */
617
- export type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
618
- T extends unknown
619
- ? number extends T['length'] ?
620
- T extends readonly [infer U, ...infer V]
621
- ? StaticPartOfArray<V, [...Result, U]>
622
- : Result
623
- : T
624
- : never; // Should never happen
625
-
626
- /**
627
- Returns the variable, non-fixed-length portion of the given array, excluding static-length parts.
628
-
629
- @example
630
- ```
631
- type A = [string, number, boolean, ...string[]];
632
- type B = VariablePartOfArray<A>;
633
- //=> string[]
634
- ```
635
- */
636
- export type VariablePartOfArray<T extends UnknownArray> =
637
- T extends unknown
638
- ? T extends readonly [...StaticPartOfArray<T>, ...infer U]
639
- ? U
640
- : []
641
- : never; // Should never happen
642
-
643
- /**
644
- Returns the minimum number in the given union of numbers.
645
-
646
- Note: Just supports numbers from 0 to 999.
647
-
648
- @example
649
- ```
650
- type A = UnionMin<3 | 1 | 2>;
651
- //=> 1
652
- ```
653
- */
654
- export type UnionMin<N extends number> = InternalUnionMin<N>;
655
-
656
- /**
657
- The actual implementation of `UnionMin`. It's private because it has some arguments that don't need to be exposed.
658
- */
659
- type InternalUnionMin<N extends number, T extends UnknownArray = []> =
660
- T['length'] extends N
661
- ? T['length']
662
- : InternalUnionMin<N, [...T, unknown]>;
663
-
664
- /**
665
- Returns the maximum number in the given union of numbers.
666
-
667
- Note: Just supports numbers from 0 to 999.
668
-
669
- @example
670
- ```
671
- type A = UnionMax<1 | 3 | 2>;
672
- //=> 3
673
- ```
674
- */
675
- export type UnionMax<N extends number> = InternalUnionMax<N>;
676
-
677
- /**
678
- The actual implementation of `UnionMax`. It's private because it has some arguments that don't need to be exposed.
679
- */
680
- type InternalUnionMax<N extends number, T extends UnknownArray = []> =
681
- IsNever<N> extends true
682
- ? T['length']
683
- : T['length'] extends N
684
- ? InternalUnionMax<Exclude<N, T['length']>, T>
685
- : InternalUnionMax<N, [...T, unknown]>;
686
-
687
- /**
688
- Returns a boolean for whether the given type is a union type.
689
-
690
- @example
691
- ```
692
- type A = IsUnion<string | number>;
693
- //=> true
694
-
695
- type B = IsUnion<string>;
696
- //=> false
697
- ```
698
- */
699
- export type IsUnion<T> = InternalIsUnion<T>;
700
-
701
- /**
702
- The actual implementation of `IsUnion`.
703
- */
704
- type InternalIsUnion<T, U = T> =
705
- (
706
- // @link https://ghaiklor.github.io/type-challenges-solutions/en/medium-isunion.html
707
- IsNever<T> extends true
708
- ? false
709
- : T extends any
710
- ? [U] extends [T]
711
- ? false
712
- : true
713
- : never
714
- ) extends infer Result
715
- // In some cases `Result` will return `false | true` which is `boolean`,
716
- // that means `T` has at least two types and it's a union type,
717
- // so we will return `true` instead of `boolean`.
718
- ? boolean extends Result ? true
719
- : Result
720
- : never; // Should never happen
721
-
722
- /**
723
- Set the given array to readonly if `IsReadonly` is `true`, otherwise set the given array to normal, then return the result.
724
-
725
- @example
726
- ```
727
- type ReadonlyArray = readonly string[];
728
- type NormalArray = string[];
729
-
730
- type ReadonlyResult = SetArrayAccess<NormalArray, true>;
731
- //=> readonly string[]
732
-
733
- type NormalResult = SetArrayAccess<ReadonlyArray, false>;
734
- //=> string[]
735
- ```
736
- */
737
- export type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
738
- T extends readonly [...infer U] ?
739
- IsReadonly extends true
740
- ? readonly [...U]
741
- : [...U]
742
- : T;
743
-
744
- /**
745
- Returns whether the given array `T` is readonly.
746
- */
747
- export type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
748
-
749
- /**
750
- Get the exact version of the given `Key` in the given object `T`.
751
-
752
- 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.
753
-
754
- @example
755
- ```
756
- type Object = {
757
- 0: number;
758
- '1': string;
759
- };
760
-
761
- type Key1 = ExactKey<Object, '0'>;
762
- //=> 0
763
- type Key2 = ExactKey<Object, 0>;
764
- //=> 0
765
-
766
- type Key3 = ExactKey<Object, '1'>;
767
- //=> '1'
768
- type Key4 = ExactKey<Object, 1>;
769
- //=> '1'
770
- ```
771
-
772
- @category Object
773
- */
774
- export type ExactKey<T extends object, Key extends PropertyKey> =
775
- Key extends keyof T
776
- ? Key
777
- : ToString<Key> extends keyof T
778
- ? ToString<Key>
779
- : Key extends `${infer NumberKey extends number}`
780
- ? NumberKey extends keyof T
781
- ? NumberKey
782
- : never
783
- : never;