@depup/type-fest 5.4.4-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/README.md +25 -0
  2. package/index.d.ts +211 -0
  3. package/license-cc0 +121 -0
  4. package/license-mit +9 -0
  5. package/package.json +85 -0
  6. package/readme.md +1052 -0
  7. package/source/all-extend.d.ts +120 -0
  8. package/source/all-union-fields.d.ts +91 -0
  9. package/source/and.d.ts +81 -0
  10. package/source/array-element.d.ts +46 -0
  11. package/source/array-indices.d.ts +25 -0
  12. package/source/array-reverse.d.ts +84 -0
  13. package/source/array-slice.d.ts +132 -0
  14. package/source/array-splice.d.ts +104 -0
  15. package/source/array-tail.d.ts +70 -0
  16. package/source/array-values.d.ts +24 -0
  17. package/source/arrayable.d.ts +31 -0
  18. package/source/async-return-type.d.ts +28 -0
  19. package/source/asyncify.d.ts +25 -0
  20. package/source/basic.d.ts +38 -0
  21. package/source/camel-case.d.ts +92 -0
  22. package/source/camel-cased-properties-deep.d.ts +99 -0
  23. package/source/camel-cased-properties.d.ts +45 -0
  24. package/source/characters.d.ts +67 -0
  25. package/source/conditional-except.d.ts +47 -0
  26. package/source/conditional-keys.d.ts +63 -0
  27. package/source/conditional-pick-deep.d.ts +120 -0
  28. package/source/conditional-pick.d.ts +46 -0
  29. package/source/conditional-simplify-deep.d.ts +73 -0
  30. package/source/conditional-simplify.d.ts +50 -0
  31. package/source/delimiter-case.d.ts +77 -0
  32. package/source/delimiter-cased-properties-deep.d.ts +108 -0
  33. package/source/delimiter-cased-properties.d.ts +48 -0
  34. package/source/distributed-omit.d.ts +96 -0
  35. package/source/distributed-pick.d.ts +92 -0
  36. package/source/empty-object.d.ts +51 -0
  37. package/source/entries.d.ts +64 -0
  38. package/source/entry.d.ts +67 -0
  39. package/source/exact.d.ts +73 -0
  40. package/source/except.d.ts +112 -0
  41. package/source/exclude-rest-element.d.ts +40 -0
  42. package/source/exclude-strict.d.ts +51 -0
  43. package/source/exclusify-union.d.ts +147 -0
  44. package/source/extends-strict.d.ts +44 -0
  45. package/source/extract-rest-element.d.ts +30 -0
  46. package/source/extract-strict.d.ts +51 -0
  47. package/source/find-global-type.d.ts +68 -0
  48. package/source/fixed-length-array.d.ts +97 -0
  49. package/source/get.d.ts +227 -0
  50. package/source/global-this.d.ts +24 -0
  51. package/source/globals/index.d.ts +3 -0
  52. package/source/globals/observable-like.d.ts +78 -0
  53. package/source/greater-than-or-equal.d.ts +30 -0
  54. package/source/greater-than.d.ts +58 -0
  55. package/source/has-optional-keys.d.ts +23 -0
  56. package/source/has-readonly-keys.d.ts +23 -0
  57. package/source/has-required-keys.d.ts +61 -0
  58. package/source/has-writable-keys.d.ts +23 -0
  59. package/source/if-any.d.ts +28 -0
  60. package/source/if-empty-object.d.ts +30 -0
  61. package/source/if-never.d.ts +28 -0
  62. package/source/if-null.d.ts +28 -0
  63. package/source/if-unknown.d.ts +28 -0
  64. package/source/if.d.ts +102 -0
  65. package/source/includes.d.ts +24 -0
  66. package/source/int-closed-range.d.ts +47 -0
  67. package/source/int-range.d.ts +69 -0
  68. package/source/internal/array.d.ts +151 -0
  69. package/source/internal/characters.d.ts +65 -0
  70. package/source/internal/enforce-optional.d.ts +49 -0
  71. package/source/internal/index.d.ts +11 -0
  72. package/source/internal/keys.d.ts +100 -0
  73. package/source/internal/numeric.d.ts +151 -0
  74. package/source/internal/object.d.ts +292 -0
  75. package/source/internal/string.d.ts +202 -0
  76. package/source/internal/tuple.d.ts +79 -0
  77. package/source/internal/type.d.ts +164 -0
  78. package/source/invariant-of.d.ts +85 -0
  79. package/source/is-any.d.ts +31 -0
  80. package/source/is-equal.d.ts +42 -0
  81. package/source/is-float.d.ts +43 -0
  82. package/source/is-integer.d.ts +60 -0
  83. package/source/is-literal.d.ts +315 -0
  84. package/source/is-lowercase.d.ts +38 -0
  85. package/source/is-never.d.ts +56 -0
  86. package/source/is-null.d.ts +22 -0
  87. package/source/is-nullable.d.ts +30 -0
  88. package/source/is-optional-key-of.d.ts +51 -0
  89. package/source/is-optional.d.ts +28 -0
  90. package/source/is-readonly-key-of.d.ts +55 -0
  91. package/source/is-required-key-of.d.ts +51 -0
  92. package/source/is-tuple.d.ts +92 -0
  93. package/source/is-undefined.d.ts +22 -0
  94. package/source/is-union.d.ts +40 -0
  95. package/source/is-unknown.d.ts +43 -0
  96. package/source/is-uppercase.d.ts +38 -0
  97. package/source/is-writable-key-of.d.ts +51 -0
  98. package/source/iterable-element.d.ts +66 -0
  99. package/source/join.d.ts +79 -0
  100. package/source/json-value.d.ts +33 -0
  101. package/source/jsonifiable.d.ts +37 -0
  102. package/source/jsonify.d.ts +127 -0
  103. package/source/kebab-case.d.ts +46 -0
  104. package/source/kebab-cased-properties-deep.d.ts +65 -0
  105. package/source/kebab-cased-properties.d.ts +42 -0
  106. package/source/key-as-string.d.ts +27 -0
  107. package/source/keys-of-union.d.ts +44 -0
  108. package/source/last-array-element.d.ts +36 -0
  109. package/source/less-than-or-equal.d.ts +24 -0
  110. package/source/less-than.d.ts +28 -0
  111. package/source/literal-to-primitive-deep.d.ts +71 -0
  112. package/source/literal-to-primitive.d.ts +38 -0
  113. package/source/literal-union.d.ts +39 -0
  114. package/source/merge-deep.d.ts +495 -0
  115. package/source/merge-exclusive.d.ts +45 -0
  116. package/source/merge.d.ts +62 -0
  117. package/source/multidimensional-array.d.ts +38 -0
  118. package/source/multidimensional-readonly-array.d.ts +38 -0
  119. package/source/non-empty-object.d.ts +38 -0
  120. package/source/non-empty-string.d.ts +32 -0
  121. package/source/non-empty-tuple.d.ts +24 -0
  122. package/source/numeric.d.ts +226 -0
  123. package/source/object-merge.d.ts +194 -0
  124. package/source/omit-deep.d.ts +154 -0
  125. package/source/omit-index-signature.d.ts +98 -0
  126. package/source/opaque.d.ts +3 -0
  127. package/source/optional-keys-of.d.ts +46 -0
  128. package/source/or.d.ts +89 -0
  129. package/source/override-properties.d.ts +43 -0
  130. package/source/package-json.d.ts +710 -0
  131. package/source/partial-deep.d.ts +155 -0
  132. package/source/partial-on-undefined-deep.d.ts +81 -0
  133. package/source/pascal-case.d.ts +51 -0
  134. package/source/pascal-cased-properties-deep.d.ts +72 -0
  135. package/source/pascal-cased-properties.d.ts +42 -0
  136. package/source/paths.d.ts +241 -0
  137. package/source/pick-deep.d.ts +152 -0
  138. package/source/pick-index-signature.d.ts +52 -0
  139. package/source/primitive.d.ts +15 -0
  140. package/source/promisable.d.ts +27 -0
  141. package/source/readonly-deep.d.ts +116 -0
  142. package/source/readonly-keys-of.d.ts +38 -0
  143. package/source/readonly-tuple.d.ts +34 -0
  144. package/source/remove-prefix.d.ts +132 -0
  145. package/source/replace.d.ts +87 -0
  146. package/source/require-all-or-none.d.ts +54 -0
  147. package/source/require-at-least-one.d.ts +50 -0
  148. package/source/require-exactly-one.d.ts +48 -0
  149. package/source/require-one-or-none.d.ts +49 -0
  150. package/source/required-deep.d.ts +76 -0
  151. package/source/required-keys-of.d.ts +38 -0
  152. package/source/schema.d.ts +119 -0
  153. package/source/screaming-snake-case.d.ts +30 -0
  154. package/source/set-field-type.d.ts +67 -0
  155. package/source/set-non-nullable-deep.d.ts +85 -0
  156. package/source/set-non-nullable.d.ts +41 -0
  157. package/source/set-optional.d.ts +46 -0
  158. package/source/set-parameter-type.d.ts +125 -0
  159. package/source/set-readonly.d.ts +44 -0
  160. package/source/set-required-deep.d.ts +64 -0
  161. package/source/set-required.d.ts +79 -0
  162. package/source/set-return-type.d.ts +31 -0
  163. package/source/shared-union-fields-deep.d.ts +180 -0
  164. package/source/shared-union-fields.d.ts +79 -0
  165. package/source/simplify-deep.d.ts +117 -0
  166. package/source/simplify.d.ts +61 -0
  167. package/source/single-key-object.d.ts +28 -0
  168. package/source/snake-case.d.ts +47 -0
  169. package/source/snake-cased-properties-deep.d.ts +65 -0
  170. package/source/snake-cased-properties.d.ts +42 -0
  171. package/source/split-on-rest-element.d.ts +106 -0
  172. package/source/split.d.ts +90 -0
  173. package/source/spread.d.ts +82 -0
  174. package/source/string-repeat.d.ts +49 -0
  175. package/source/string-slice.d.ts +39 -0
  176. package/source/stringified.d.ts +25 -0
  177. package/source/structured-cloneable.d.ts +89 -0
  178. package/source/subtract.d.ts +86 -0
  179. package/source/sum.d.ts +81 -0
  180. package/source/tagged-union.d.ts +53 -0
  181. package/source/tagged.d.ts +263 -0
  182. package/source/trim.d.ts +29 -0
  183. package/source/tsconfig-json.d.ts +1324 -0
  184. package/source/tuple-of.d.ts +80 -0
  185. package/source/tuple-to-object.d.ts +47 -0
  186. package/source/tuple-to-union.d.ts +54 -0
  187. package/source/typed-array.d.ts +19 -0
  188. package/source/undefined-on-partial-deep.d.ts +83 -0
  189. package/source/union-to-intersection.d.ts +35 -0
  190. package/source/union-to-tuple.d.ts +58 -0
  191. package/source/unknown-array.d.ts +27 -0
  192. package/source/unknown-map.d.ts +26 -0
  193. package/source/unknown-record.d.ts +33 -0
  194. package/source/unknown-set.d.ts +26 -0
  195. package/source/unwrap-partial.d.ts +33 -0
  196. package/source/value-of.d.ts +24 -0
  197. package/source/words.d.ts +122 -0
  198. package/source/writable-deep.d.ts +84 -0
  199. package/source/writable-keys-of.d.ts +34 -0
  200. package/source/writable.d.ts +72 -0
  201. package/source/xor.d.ts +83 -0
@@ -0,0 +1,147 @@
1
+ import type {If} from './if.d.ts';
2
+ import type {IfNotAnyOrNever, MapsSetsOrArrays, NonRecursiveType} from './internal/type.d.ts';
3
+ import type {IsUnknown} from './is-unknown.d.ts';
4
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
5
+ import type {Simplify} from './simplify.d.ts';
6
+
7
+ /**
8
+ Ensure mutual exclusivity in object unions by adding other members’ keys as `?: never`.
9
+
10
+ Use-cases:
11
+ - You want each union member to be exclusive, preventing overlapping object shapes.
12
+ - You want to safely access any property defined across the union without additional type guards.
13
+
14
+ @example
15
+ ```
16
+ import type {ExclusifyUnion} from 'type-fest';
17
+
18
+ type FileConfig = {
19
+ filePath: string;
20
+ };
21
+
22
+ type InlineConfig = {
23
+ content: string;
24
+ };
25
+
26
+ declare function loadConfig1(options: FileConfig | InlineConfig): void;
27
+
28
+ // Someone could mistakenly provide both `filePath` and `content`.
29
+ loadConfig1({filePath: './config.json', content: '{ "name": "app" }'}); // No errors
30
+
31
+ // Use `ExclusifyUnion` to prevent that mistake.
32
+ type Config = ExclusifyUnion<FileConfig | InlineConfig>;
33
+ //=> {
34
+ // filePath: string;
35
+ // content?: never;
36
+ // } | {
37
+ // content: string;
38
+ // filePath?: never;
39
+ // }
40
+
41
+ declare function loadConfig2(options: Config): void;
42
+
43
+ // @ts-expect-error
44
+ loadConfig2({filePath: './config.json', content: '{ "name": "app" }'});
45
+ // Error: Argument of type '{ filePath: string; content: string; }' is not assignable to parameter of type '{ filePath: string; content?: never; } | { content: string; filePath?: never; }'.
46
+
47
+ loadConfig2({filePath: './config.json'}); // Ok
48
+
49
+ loadConfig2({content: '{ "name": "app" }'}); // Ok
50
+ ```
51
+
52
+ @example
53
+ ```
54
+ import type {ExclusifyUnion} from 'type-fest';
55
+
56
+ type CardPayment = {
57
+ amount: number;
58
+ cardNumber: string;
59
+ };
60
+
61
+ type PaypalPayment = {
62
+ amount: number;
63
+ paypalId: string;
64
+ };
65
+
66
+ function processPayment1(payment: CardPayment | PaypalPayment) {
67
+ // @ts-expect-error
68
+ const details = payment.cardNumber ?? payment.paypalId; // Cannot access `cardNumber` or `paypalId` directly
69
+ }
70
+
71
+ type Payment = ExclusifyUnion<CardPayment | PaypalPayment>;
72
+ //=> {
73
+ // amount: number;
74
+ // cardNumber: string;
75
+ // paypalId?: never;
76
+ // } | {
77
+ // amount: number;
78
+ // paypalId: string;
79
+ // cardNumber?: never;
80
+ // }
81
+
82
+ function processPayment2(payment: Payment) {
83
+ const details = payment.cardNumber ?? payment.paypalId; // Ok
84
+ //=> string
85
+ }
86
+ ```
87
+
88
+ @example
89
+ ```
90
+ import type {ExclusifyUnion} from 'type-fest';
91
+
92
+ type A = ExclusifyUnion<{a: string} | {b: number}>;
93
+ //=> {a: string; b?: never} | {b: number; a?: never}
94
+
95
+ type B = ExclusifyUnion<{a: string} | {b: number} | {c: boolean}>;
96
+ //=> {
97
+ // a: string;
98
+ // b?: never;
99
+ // c?: never;
100
+ // } | {
101
+ // b: number;
102
+ // a?: never;
103
+ // c?: never;
104
+ // } | {
105
+ // c: boolean;
106
+ // a?: never;
107
+ // b?: never;
108
+ // }
109
+
110
+ type C = ExclusifyUnion<{a: string; b: number} | {b: string; c: number}>;
111
+ //=> {
112
+ // a: string;
113
+ // b: number;
114
+ // c?: never;
115
+ // } | {
116
+ // b: string;
117
+ // c: number;
118
+ // a?: never;
119
+ // }
120
+
121
+ type D = ExclusifyUnion<{a?: 1; readonly b: 2} | {d: 4}>;
122
+ //=> {a?: 1; readonly b: 2; d?: never} | {d: 4; a?: never; b?: never}
123
+ ```
124
+
125
+ @category Object
126
+ @category Union
127
+ */
128
+ export type ExclusifyUnion<Union> = IfNotAnyOrNever<Union,
129
+ If<IsUnknown<Union>, Union,
130
+ Extract<Union, NonRecursiveType | MapsSetsOrArrays> extends infer SkippedMembers
131
+ ? SkippedMembers | _ExclusifyUnion<Exclude<Union, SkippedMembers>>
132
+ : never
133
+ >
134
+ >;
135
+
136
+ type _ExclusifyUnion<Union, UnionCopy = Union> = Union extends unknown // For distributing `Union`
137
+ ? Simplify<
138
+ Union & Partial<
139
+ Record<
140
+ Exclude<KeysOfUnion<UnionCopy>, keyof Union>,
141
+ never
142
+ >
143
+ >
144
+ >
145
+ : never; // Should never happen
146
+
147
+ export {};
@@ -0,0 +1,44 @@
1
+ import type {IsNever} from './is-never.d.ts';
2
+ import type {IsAny} from './is-any.d.ts';
3
+
4
+ /**
5
+ A stricter, non-distributive version of `extends` for checking whether one type is assignable to another.
6
+
7
+ Unlike the built-in `extends` keyword, `ExtendsStrict`:
8
+
9
+ 1. Prevents distribution over union types by wrapping both types in tuples. For example, `ExtendsStrict<string | number, number>` returns `false`, whereas `string | number extends number` would result in `boolean`.
10
+
11
+ 2. Treats `never` as a special case: `never` doesn't extend every other type, it only extends itself (or `any`). For example, `ExtendsStrict<never, number>` returns `false` whereas `never extends number` would result in `true`.
12
+
13
+ @example
14
+ ```
15
+ import type {ExtendsStrict} from 'type-fest';
16
+
17
+ type T1 = ExtendsStrict<number | string, string>;
18
+ //=> false
19
+
20
+ type T2 = ExtendsStrict<never, number>;
21
+ //=> false
22
+
23
+ type T3 = ExtendsStrict<never, never>;
24
+ //=> true
25
+
26
+ type T4 = ExtendsStrict<string, number | string>;
27
+ //=> true
28
+
29
+ type T5 = ExtendsStrict<string, string>;
30
+ //=> true
31
+ ```
32
+
33
+ @category Improved Built-in
34
+ */
35
+ export type ExtendsStrict<Left, Right> =
36
+ IsAny<Left | Right> extends true
37
+ ? true
38
+ : IsNever<Left> extends true
39
+ ? IsNever<Right>
40
+ : [Left] extends [Right]
41
+ ? true
42
+ : false;
43
+
44
+ export {};
@@ -0,0 +1,30 @@
1
+ import type {SplitOnRestElement} from './split-on-rest-element.d.ts';
2
+ import type {UnknownArray} from './unknown-array.d.ts';
3
+
4
+ /**
5
+ Extract the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element type from an array.
6
+
7
+ @example
8
+ ```
9
+ import type {ExtractRestElement} from 'type-fest';
10
+
11
+ type T1 = ExtractRestElement<[number, ...string[], string, 'foo']>;
12
+ //=> string
13
+
14
+ type T2 = ExtractRestElement<[...boolean[], string]>;
15
+ //=> boolean
16
+
17
+ type T3 = ExtractRestElement<[...Array<'foo'>, true]>;
18
+ //=> 'foo'
19
+
20
+ type T4 = ExtractRestElement<[number, string]>;
21
+ //=> never
22
+ ```
23
+
24
+ @see {@link ExcludeRestElement}
25
+ @see {@link SplitOnRestElement}
26
+ @category Array
27
+ */
28
+ export type ExtractRestElement<T extends UnknownArray> = SplitOnRestElement<T>[1][number];
29
+
30
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ A stricter version of {@link Extract<T, U>} that ensures every member of `U` can successfully extract something from `T`.
3
+
4
+ For example, `ExtractStrict<string | number | boolean, number | bigint>` will error because `bigint` cannot extract anything from `string | number | boolean`.
5
+
6
+ @example
7
+ ```
8
+ // Valid Examples
9
+ import type {ExtractStrict} from 'type-fest';
10
+
11
+ type Example1 = ExtractStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>;
12
+ //=> {status: 'success'; data: string[]}
13
+
14
+ type Example2 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>;
15
+ //=> 'xs' | 's'
16
+
17
+ type Example3 = ExtractStrict<{x: number; y: number} | [number, number], unknown[]>;
18
+ //=> [number, number]
19
+ ```
20
+
21
+ @example
22
+ ```
23
+ // Invalid Examples
24
+ import type {ExtractStrict} from 'type-fest';
25
+
26
+ // `'xxl'` cannot extract anything from `'xs' | 's' | 'm' | 'l' | 'xl'`
27
+ // @ts-expect-error
28
+ type Example1 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>;
29
+ // ~~~~~~~~~~~~
30
+ // Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'.
31
+
32
+ // `unknown[]` cannot extract anything from `{x: number; y: number} | {x: string; y: string}`
33
+ // @ts-expect-error
34
+ type Example2 = ExtractStrict<{x: number; y: number} | {x: string; y: string}, unknown[]>;
35
+ // ~~~~~~~~~
36
+ // Error: Type 'unknown[]' does not satisfy the constraint 'never'.
37
+ ```
38
+
39
+ @category Improved Built-in
40
+ */
41
+ export type ExtractStrict<
42
+ T,
43
+ U extends [U] extends [
44
+ // Ensure every member of `U` extracts something from `T`
45
+ U extends unknown ? (Extract<T, U> extends never ? never : U) : never,
46
+ ]
47
+ ? unknown
48
+ : never,
49
+ > = Extract<T, U>;
50
+
51
+ export {};
@@ -0,0 +1,68 @@
1
+ /**
2
+ Tries to find the type of a global with the given name.
3
+
4
+ Limitations: Due to peculiarities with the behavior of `globalThis`, "globally defined" only includes `var` declarations in `declare global` blocks, not `let` or `const` declarations.
5
+
6
+ @example
7
+ ```
8
+ import type {FindGlobalType} from 'type-fest';
9
+
10
+ declare global {
11
+ const foo: number; // let and const don't work
12
+ var bar: string; // var works
13
+ }
14
+
15
+ type FooType = FindGlobalType<'foo'>; //=> never (let/const don't work)
16
+ type BarType = FindGlobalType<'bar'>; //=> string
17
+ type OtherType = FindGlobalType<'other'>; //=> never (no global named 'other')
18
+ ```
19
+
20
+ @category Utilities
21
+ */
22
+ export type FindGlobalType<Name extends string> = typeof globalThis extends Record<Name, infer T> ? T : never;
23
+
24
+ /**
25
+ Tries to find one or more types from their globally-defined constructors.
26
+
27
+ Use-case: Conditionally referencing DOM types only when the DOM library present.
28
+
29
+ *Limitations:* Due to peculiarities with the behavior of `globalThis`, "globally defined" has a narrow definition in this case. Declaring a class in a `declare global` block won't work, instead you must declare its type using an interface and declare its constructor as a `var` (*not* `let`/`const`) inside the `declare global` block.
30
+
31
+ @example
32
+ ```
33
+ import type {FindGlobalInstanceType} from 'type-fest';
34
+
35
+ class Point {
36
+ constructor(public x: number, public y: number) {}
37
+ }
38
+
39
+ type PointLike = Point | FindGlobalInstanceType<'DOMPoint'>;
40
+ ```
41
+
42
+ @example
43
+ ```
44
+ import type {FindGlobalInstanceType} from 'type-fest';
45
+
46
+ declare global {
47
+ // Class syntax won't add the key to `globalThis`
48
+ class Foo {}
49
+
50
+ // interface + constructor style works
51
+ interface Bar {
52
+ bar: string;
53
+ }
54
+ var Bar: new () => Bar; // Not let or const
55
+ }
56
+
57
+ type FindFoo = FindGlobalInstanceType<'Foo'>; // Doesn't work
58
+ type FindBar = FindGlobalInstanceType<'Bar'>; // Works
59
+ ```
60
+
61
+ @category Utilities
62
+ */
63
+ export type FindGlobalInstanceType<Name extends string> =
64
+ Name extends string
65
+ ? typeof globalThis extends Record<Name, abstract new (...arguments_: any[]) => infer T> ? T : never
66
+ : never;
67
+
68
+ export {};
@@ -0,0 +1,97 @@
1
+ import type {Except} from './except.d.ts';
2
+ import type {TupleOf} from './tuple-of.d.ts';
3
+
4
+ /**
5
+ Methods to exclude.
6
+ */
7
+ type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift';
8
+
9
+ /**
10
+ Create a type that represents an array of the given type and length. The `Array` prototype methods that manipulate its length are excluded from the resulting type.
11
+
12
+ The problem with the built-in tuple type is that it allows mutating methods like `push`, `pop` etc, which can cause issues, like in the following example:
13
+
14
+ @example
15
+ ```
16
+ const color: [number, number, number] = [255, 128, 64];
17
+
18
+ function toHex([r, g, b]: readonly [number, number, number]) {
19
+ return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
20
+ }
21
+
22
+ color.pop(); // Allowed
23
+
24
+ console.log(toHex(color)); // Compiles fine, but fails at runtime since index `2` no longer contains a `number`.
25
+ ```
26
+
27
+ `ArrayLengthMutationKeys` solves this problem by excluding methods like `push`, `pop` etc from the resulting type.
28
+
29
+ @example
30
+ ```
31
+ import type {FixedLengthArray} from 'type-fest';
32
+
33
+ const color: FixedLengthArray<number, 3> = [255, 128, 64];
34
+
35
+ // @ts-expect-error
36
+ color.pop();
37
+ // Error: Property 'pop' does not exist on type 'FixedLengthArray<number, 3>'.
38
+ ```
39
+
40
+ Use-cases:
41
+ - Declaring fixed-length tuples or arrays with a large number of items.
42
+ - Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector.
43
+
44
+ @example
45
+ ```
46
+ import type {FixedLengthArray} from 'type-fest';
47
+
48
+ let color: FixedLengthArray<number, 3> = [255, 128, 64];
49
+
50
+ const red = color[0];
51
+ //=> number
52
+ const green = color[1];
53
+ //=> number
54
+ const blue = color[2];
55
+ //=> number
56
+
57
+ // @ts-expect-error
58
+ const alpha = color[3];
59
+ // Error: Property '3' does not exist on type 'FixedLengthArray<number, 3>'.
60
+
61
+ // You can write to valid indices.
62
+ color[0] = 128;
63
+ color[1] = 64;
64
+ color[2] = 32;
65
+
66
+ // But you cannot write to out-of-bounds indices.
67
+ // @ts-expect-error
68
+ color[3] = 0.5;
69
+ // Error: Property '3' does not exist on type 'FixedLengthArray<number, 3>'.
70
+
71
+ // @ts-expect-error
72
+ color.push(0.5);
73
+ // Error: Property 'push' does not exist on type 'FixedLengthArray<number, 3>'.
74
+
75
+ // @ts-expect-error
76
+ color = [0, 128, 255, 0.5];
77
+ // Error: Type '[number, number, number, number]' is not assignable to type 'FixedLengthArray<number, 3>'. Types of property 'length' are incompatible.
78
+
79
+ // @ts-expect-error
80
+ color.length = 4;
81
+ // Error: Cannot assign to 'length' because it is a read-only property.
82
+
83
+ function toHex([r, g, b]: readonly [number, number, number]) {
84
+ return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`;
85
+ }
86
+
87
+ console.log(toHex(color)); // `FixedLengthArray<number, 3>` is assignable to `readonly [number, number, number]`.
88
+ ```
89
+
90
+ @category Array
91
+ */
92
+ export type FixedLengthArray<Element, Length extends number> =
93
+ Except<TupleOf<Length, Element>, ArrayLengthMutationKeys | number | 'length'>
94
+ & {readonly length: Length}
95
+ & (number extends Length ? {[n: number]: Element} : {}); // Add `number` index signature only for non-tuple arrays.
96
+
97
+ export {};
@@ -0,0 +1,227 @@
1
+ import type {ApplyDefaultOptions, ToString} from './internal/index.d.ts';
2
+ import type {_LiteralStringUnion} from './literal-union.d.ts';
3
+ import type {Paths} from './paths.d.ts';
4
+ import type {Split} from './split.d.ts';
5
+ import type {KeyAsString} from './key-as-string.d.ts';
6
+ import type {DigitCharacter} from './characters.d.ts';
7
+
8
+ export type GetOptions = {
9
+ /**
10
+ Include `undefined` in the return type when accessing properties.
11
+
12
+ Setting this to `false` is not recommended.
13
+
14
+ @default true
15
+ */
16
+ strict?: boolean;
17
+ };
18
+
19
+ type DefaultGetOptions = {
20
+ strict: true;
21
+ };
22
+
23
+ /**
24
+ Like the `Get` type but receives an array of strings as a path parameter.
25
+ */
26
+ type GetWithPath<BaseType, Keys, Options extends Required<GetOptions>> =
27
+ Keys extends readonly []
28
+ ? BaseType
29
+ : Keys extends readonly [infer Head, ...infer Tail]
30
+ ? GetWithPath<
31
+ PropertyOf<BaseType, Extract<Head, string>, Options>,
32
+ Extract<Tail, string[]>,
33
+ Options
34
+ >
35
+ : never;
36
+
37
+ /**
38
+ Adds `undefined` to `Type` if `strict` is enabled.
39
+ */
40
+ type Strictify<Type, Options extends Required<GetOptions>> =
41
+ Options['strict'] extends false ? Type : (Type | undefined);
42
+
43
+ /**
44
+ If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record<string, any>`.
45
+
46
+ Known limitations:
47
+ - Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`).
48
+ */
49
+ type StrictPropertyOf<BaseType, Key extends keyof BaseType, Options extends Required<GetOptions>> =
50
+ Record<string, any> extends BaseType
51
+ ? string extends keyof BaseType
52
+ ? Strictify<BaseType[Key], Options> // Record<string, any>
53
+ : BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties)
54
+ : BaseType[Key];
55
+
56
+ /**
57
+ Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation.
58
+
59
+ @example
60
+ ```
61
+ type A = ToPath<'foo.bar.baz'>;
62
+ //=> ['foo', 'bar', 'baz']
63
+
64
+ type B = ToPath<'foo[0].bar.baz'>;
65
+ //=> ['foo', '0', 'bar', 'baz']
66
+ ```
67
+ */
68
+ type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.', {strictLiteralChecks: false}>;
69
+
70
+ /**
71
+ Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`.
72
+ */
73
+ type FixPathSquareBrackets<Path extends string> =
74
+ Path extends `[${infer Head}]${infer Tail}`
75
+ ? Tail extends `[${string}`
76
+ ? `${Head}.${FixPathSquareBrackets<Tail>}`
77
+ : `${Head}${FixPathSquareBrackets<Tail>}`
78
+ : Path extends `${infer Head}[${infer Middle}]${infer Tail}`
79
+ ? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}`
80
+ : Path;
81
+
82
+ /**
83
+ Returns true if `LongString` is made up out of `Substring` repeated 0 or more times.
84
+
85
+ @example
86
+ ```
87
+ type A = ConsistsOnlyOf<'aaa', 'a'>; //=> true
88
+ type B = ConsistsOnlyOf<'ababab', 'ab'>; //=> true
89
+ type C = ConsistsOnlyOf<'aBa', 'a'>; //=> false
90
+ type D = ConsistsOnlyOf<'', 'a'>; //=> true
91
+ ```
92
+ */
93
+ type ConsistsOnlyOf<LongString extends string, Substring extends string> =
94
+ LongString extends ''
95
+ ? true
96
+ : LongString extends `${Substring}${infer Tail}`
97
+ ? ConsistsOnlyOf<Tail, Substring>
98
+ : false;
99
+
100
+ /**
101
+ Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types.
102
+
103
+ @example
104
+ ```
105
+ type WithNumbers = {foo: string; 0: boolean};
106
+ type WithStrings = WithStringKeys<WithNumbers>;
107
+
108
+ type WithNumbersKeys = keyof WithNumbers;
109
+ //=> 'foo' | 0
110
+ type WithStringsKeys = keyof WithStrings;
111
+ //=> 'foo' | '0'
112
+ ```
113
+ */
114
+ type WithStringKeys<BaseType> = {
115
+ [Key in KeyAsString<BaseType>]: UncheckedIndex<BaseType, Key>
116
+ };
117
+
118
+ /**
119
+ Perform a `T[U]` operation if `T` supports indexing.
120
+ */
121
+ type UncheckedIndex<T, U extends string | number> = [T] extends [Record<string | number, any>] ? T[U] : never;
122
+
123
+ /**
124
+ 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.
125
+
126
+ Note:
127
+ - 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.
128
+ - Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc.
129
+ */
130
+ type PropertyOf<BaseType, Key extends string, Options extends Required<GetOptions>> =
131
+ BaseType extends null | undefined
132
+ ? undefined
133
+ : Key extends keyof BaseType
134
+ ? StrictPropertyOf<BaseType, Key, Options>
135
+ // Handle arrays and tuples
136
+ : BaseType extends readonly unknown[]
137
+ ? Key extends `${number}`
138
+ // For arrays with unknown length (regular arrays)
139
+ ? number extends BaseType['length']
140
+ ? Strictify<BaseType[number], Options>
141
+ // For tuples: check if the index is valid
142
+ : Key extends keyof BaseType
143
+ ? Strictify<BaseType[Key & keyof BaseType], Options>
144
+ // Out-of-bounds access for tuples
145
+ : unknown
146
+ // Non-numeric string key for arrays/tuples
147
+ : unknown
148
+ // Handle array-like objects
149
+ : BaseType extends {
150
+ [n: number]: infer Item;
151
+ length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
152
+ }
153
+ ? (
154
+ ConsistsOnlyOf<Key, DigitCharacter> extends true
155
+ ? Strictify<Item, Options>
156
+ : unknown
157
+ )
158
+ : Key extends keyof WithStringKeys<BaseType>
159
+ ? StrictPropertyOf<WithStringKeys<BaseType>, Key, Options>
160
+ : unknown;
161
+
162
+ // 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.
163
+ /**
164
+ Get a deeply-nested property from an object using a key path, like Lodash's `.get()` function.
165
+
166
+ Use-case: Retrieve a property from deep inside an API response or some other complex object.
167
+
168
+ @example
169
+ ```
170
+ import type {Get} from 'type-fest';
171
+
172
+ declare function get<BaseType, const Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path>;
173
+
174
+ type ApiResponse = {
175
+ hits: {
176
+ hits: Array<{
177
+ _id: string;
178
+ _source: {
179
+ name: Array<{
180
+ given: string[];
181
+ family: string;
182
+ }>;
183
+ birthDate: string;
184
+ };
185
+ }>;
186
+ };
187
+ };
188
+
189
+ const getName = (apiResponse: ApiResponse) => get(apiResponse, 'hits.hits[0]._source.name');
190
+ //=> (apiResponse: ApiResponse) => {
191
+ // given: string[];
192
+ // family: string;
193
+ // }[] | undefined
194
+
195
+ // Path also supports a readonly array of strings
196
+ const getNameWithPathArray = (apiResponse: ApiResponse) => get(apiResponse, ['hits', 'hits', '0', '_source', 'name']);
197
+ //=> (apiResponse: ApiResponse) => {
198
+ // given: string[];
199
+ // family: string;
200
+ // }[] | undefined
201
+
202
+ // Non-strict mode:
203
+ type A = Get<string[], '3', {strict: false}>;
204
+ //=> string
205
+
206
+ type B = Get<Record<string, string>, 'foo', {strict: true}>;
207
+ //=> string | undefined
208
+ ```
209
+
210
+ @category Object
211
+ @category Array
212
+ @category Template literal
213
+ */
214
+ export type Get<
215
+ BaseType,
216
+ Path extends
217
+ | readonly string[]
218
+ | _LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
219
+ Options extends GetOptions = {},
220
+ > =
221
+ GetWithPath<
222
+ BaseType,
223
+ Path extends string ? ToPath<Path> : Path,
224
+ ApplyDefaultOptions<GetOptions, DefaultGetOptions, Options>
225
+ >;
226
+
227
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ Declare locally scoped properties on `globalThis`.
3
+
4
+ When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`.
5
+
6
+ Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`.
7
+
8
+ @example
9
+ ```
10
+ import type {GlobalThis} from 'type-fest';
11
+
12
+ type ExtraGlobals = GlobalThis & {
13
+ readonly GLOBAL_TOKEN: string;
14
+ };
15
+
16
+ const globalToken = (globalThis as ExtraGlobals).GLOBAL_TOKEN;
17
+ //=> string
18
+ ```
19
+
20
+ @category Type
21
+ */
22
+ export type GlobalThis = typeof globalThis;
23
+
24
+ export {};
@@ -0,0 +1,3 @@
1
+ export type * from './observable-like.d.ts';
2
+
3
+ export {};