@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,92 @@
1
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
2
+
3
+ /**
4
+ Pick keys from a type, distributing the operation over a union.
5
+
6
+ TypeScript's `Pick` doesn't distribute over unions, leading to the erasure of unique properties from union members when picking keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Pick. Essentially, using `Pick` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.
7
+
8
+ Example:
9
+
10
+ ```
11
+ type A = {
12
+ discriminant: 'A';
13
+ foo: {
14
+ bar: string;
15
+ };
16
+ };
17
+
18
+ type B = {
19
+ discriminant: 'B';
20
+ foo: {
21
+ baz: string;
22
+ };
23
+ };
24
+
25
+ type Union = A | B;
26
+
27
+ type PickedUnion = Pick<Union, 'discriminant' | 'foo'>;
28
+ //=> {discriminant: 'A' | 'B'; foo: {bar: string} | {baz: string}}
29
+
30
+ declare const pickedUnion: PickedUnion;
31
+
32
+ if (pickedUnion.discriminant === 'A') {
33
+ // We would like to narrow `pickedUnion`'s type
34
+ // to `A` here, but we can't because `Pick`
35
+ // doesn't distribute over unions.
36
+
37
+ // @ts-expect-error
38
+ const barValue = pickedUnion.foo.bar;
39
+ // Error: Property 'bar' does not exist on type '{bar: string} | {baz: string}'.
40
+ }
41
+ ```
42
+
43
+ @example
44
+ ```
45
+ import type {DistributedPick} from 'type-fest';
46
+
47
+ type A = {
48
+ discriminant: 'A';
49
+ foo: {
50
+ bar: string;
51
+ };
52
+ extraneous: boolean;
53
+ };
54
+
55
+ type B = {
56
+ discriminant: 'B';
57
+ foo: {
58
+ baz: string;
59
+ };
60
+ extraneous: boolean;
61
+ };
62
+
63
+ // Notice that `foo.bar` exists in `A` but not in `B`.
64
+
65
+ type Union = A | B;
66
+
67
+ type PickedUnion = DistributedPick<Union, 'discriminant' | 'foo'>;
68
+
69
+ declare const pickedUnion: PickedUnion;
70
+
71
+ if (pickedUnion.discriminant === 'A') {
72
+ const barValue = pickedUnion.foo.bar;
73
+ // OK
74
+
75
+ // @ts-expect-error
76
+ const extraneousValue = pickedUnion.extraneous;
77
+ // Error: Property `extraneous` does not exist on type `Pick<A, 'discriminant' | 'foo'>`.
78
+
79
+ // @ts-expect-error
80
+ const bazValue = pickedUnion.foo.baz;
81
+ // Error: `bar` is not a property of `{discriminant: 'A'; a: string}`.
82
+ }
83
+ ```
84
+
85
+ @category Object
86
+ */
87
+ export type DistributedPick<ObjectType, KeyType extends KeysOfUnion<ObjectType>> =
88
+ ObjectType extends unknown
89
+ ? Pick<ObjectType, Extract<KeyType, keyof ObjectType>>
90
+ : never;
91
+
92
+ export {};
@@ -0,0 +1,51 @@
1
+ declare const emptyObjectSymbol: unique symbol;
2
+
3
+ /**
4
+ Represents a strictly empty plain object, the `{}` value.
5
+
6
+ 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)).
7
+
8
+ @example
9
+ ```
10
+ import type {EmptyObject} from 'type-fest';
11
+
12
+ // The following illustrates the problem with `{}`.
13
+ const foo1: {} = {}; // Pass
14
+ const foo2: {} = []; // Pass
15
+ const foo3: {} = 42; // Pass
16
+ const foo4: {} = {a: 1}; // Pass
17
+
18
+ // With `EmptyObject` only the first case is valid.
19
+ const bar1: EmptyObject = {}; // Pass
20
+ // @ts-expect-error
21
+ const bar2: EmptyObject = []; // Fail
22
+ // @ts-expect-error
23
+ const bar3: EmptyObject = 42; // Fail
24
+ // @ts-expect-error
25
+ const bar4: EmptyObject = {a: 1}; // Fail
26
+ ```
27
+
28
+ 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}.
29
+
30
+ @category Object
31
+ */
32
+ export type EmptyObject = {[emptyObjectSymbol]?: never};
33
+
34
+ /**
35
+ Returns a `boolean` for whether the type is strictly equal to an empty plain object, the `{}` value.
36
+
37
+ @example
38
+ ```
39
+ import type {IsEmptyObject} from 'type-fest';
40
+
41
+ type Pass = IsEmptyObject<{}>; //=> true
42
+ type Fail1 = IsEmptyObject<[]>; //=> false
43
+ type Fail2 = IsEmptyObject<null>; //=> false
44
+ ```
45
+
46
+ @see {@link EmptyObject}
47
+ @category Object
48
+ */
49
+ export type IsEmptyObject<T> = T extends EmptyObject ? true : false;
50
+
51
+ export {};
@@ -0,0 +1,64 @@
1
+ import type {_ArrayEntry, _MapEntry, _ObjectEntry, _SetEntry} from './entry.d.ts';
2
+
3
+ type ArrayEntries<BaseType extends readonly unknown[]> = Array<_ArrayEntry<BaseType>>;
4
+ type MapEntries<BaseType> = Array<_MapEntry<BaseType>>;
5
+ type ObjectEntries<BaseType> = Array<_ObjectEntry<BaseType>>;
6
+ type SetEntries<BaseType extends Set<unknown>> = Array<_SetEntry<BaseType>>;
7
+
8
+ /**
9
+ Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entries` type will return the type of that collection's entries.
10
+
11
+ For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable.
12
+
13
+ @see `Entry` if you want to just access the type of a single entry.
14
+
15
+ @example
16
+ ```
17
+ import type {Entries} from 'type-fest';
18
+
19
+ type Example = {
20
+ someKey: number;
21
+ };
22
+
23
+ const manipulatesEntries = (examples: Entries<Example>) => examples.map(example => [
24
+ // Does some arbitrary processing on the key (with type information available)
25
+ example[0].toUpperCase(),
26
+
27
+ // Does some arbitrary processing on the value (with type information available)
28
+ example[1].toFixed(0),
29
+ ]);
30
+
31
+ const example: Example = {someKey: 1};
32
+ const entries = Object.entries(example) as Entries<Example>;
33
+ const output = manipulatesEntries(entries);
34
+
35
+ // Objects
36
+ const objectExample = {a: 1};
37
+ const objectEntries: Entries<typeof objectExample> = [['a', 1]];
38
+
39
+ // Arrays
40
+ const arrayExample = ['a', 1];
41
+ const arrayEntries: Entries<typeof arrayExample> = [[0, 'a'], [1, 1]];
42
+
43
+ // Maps
44
+ const mapExample = new Map([['a', 1]]);
45
+ const mapEntries: Entries<typeof mapExample> = [['a', 1]];
46
+
47
+ // Sets
48
+ const setExample = new Set(['a', 1]);
49
+ const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]];
50
+ ```
51
+
52
+ @category Object
53
+ @category Map
54
+ @category Set
55
+ @category Array
56
+ */
57
+ export type Entries<BaseType> =
58
+ BaseType extends Map<unknown, unknown> ? MapEntries<BaseType>
59
+ : BaseType extends Set<unknown> ? SetEntries<BaseType>
60
+ : BaseType extends readonly unknown[] ? ArrayEntries<BaseType>
61
+ : BaseType extends object ? ObjectEntries<BaseType>
62
+ : never;
63
+
64
+ export {};
@@ -0,0 +1,67 @@
1
+ type MapKey<BaseType> = BaseType extends Map<infer KeyType, unknown> ? KeyType : never;
2
+ type MapValue<BaseType> = BaseType extends Map<unknown, infer ValueType> ? ValueType : never;
3
+
4
+ export type _ArrayEntry<BaseType extends readonly unknown[]> = [number, BaseType[number]];
5
+ export type _MapEntry<BaseType> = [MapKey<BaseType>, MapValue<BaseType>];
6
+ export type _ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]];
7
+ export type _SetEntry<BaseType> = BaseType extends Set<infer ItemType> ? [ItemType, ItemType] : never;
8
+
9
+ /**
10
+ Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entry` type will return the type of that collection's entry.
11
+
12
+ For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable.
13
+
14
+ @see `Entries` if you want to just access the type of the array of entries (which is the return of the `.entries()` method).
15
+
16
+ @example
17
+ ```
18
+ import type {Entry} from 'type-fest';
19
+
20
+ type Example = {
21
+ someKey: number;
22
+ };
23
+
24
+ const manipulatesEntry = (example: Entry<Example>) => [
25
+ // Does some arbitrary processing on the key (with type information available)
26
+ example[0].toUpperCase(),
27
+
28
+ // Does some arbitrary processing on the value (with type information available)
29
+ example[1].toFixed(0),
30
+ ];
31
+
32
+ const example: Example = {someKey: 1};
33
+ const entry = Object.entries(example)[0] as Entry<Example>;
34
+ const output = manipulatesEntry(entry);
35
+
36
+ // Objects
37
+ const objectExample = {a: 1};
38
+ const objectEntry: Entry<typeof objectExample> = ['a', 1];
39
+
40
+ // Arrays
41
+ const arrayExample = ['a', 1];
42
+ const arrayEntryString: Entry<typeof arrayExample> = [0, 'a'];
43
+ const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1];
44
+
45
+ // Maps
46
+ const mapExample = new Map([['a', 1]]);
47
+ const mapEntry: Entry<typeof mapExample> = ['a', 1];
48
+
49
+ // Sets
50
+ const setExample = new Set(['a', 1]);
51
+ const setEntryString: Entry<typeof setExample> = ['a', 'a'];
52
+ const setEntryNumber: Entry<typeof setExample> = [1, 1];
53
+ ```
54
+
55
+ @category Object
56
+ @category Map
57
+ @category Array
58
+ @category Set
59
+ */
60
+ export type Entry<BaseType> =
61
+ BaseType extends Map<unknown, unknown> ? _MapEntry<BaseType>
62
+ : BaseType extends Set<unknown> ? _SetEntry<BaseType>
63
+ : BaseType extends readonly unknown[] ? _ArrayEntry<BaseType>
64
+ : BaseType extends object ? _ObjectEntry<BaseType>
65
+ : never;
66
+
67
+ export {};
@@ -0,0 +1,73 @@
1
+ import type {ObjectValue} from './internal/index.d.ts';
2
+ import type {ArrayElement} from './array-element.d.ts';
3
+ import type {IsEqual} from './is-equal.d.ts';
4
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
5
+ import type {IsUnknown} from './is-unknown.d.ts';
6
+ import type {Primitive} from './primitive.d.ts';
7
+
8
+ /**
9
+ Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
10
+ - Generate a list of keys that exists in `InputType` but not in `ParameterType`.
11
+ - Mark these excess keys as `never`.
12
+ */
13
+ type ExactObject<ParameterType, InputType> = {[Key in keyof ParameterType]: Exact<ParameterType[Key], ObjectValue<InputType, Key>>}
14
+ & Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>;
15
+
16
+ /**
17
+ Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared.
18
+
19
+ This is useful for function type-guarding to reject arguments with excess properties. Due to the nature of TypeScript, it does not complain if excess properties are provided unless the provided value is an object literal.
20
+
21
+ *Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/12936) if you want to have this type as a built-in in TypeScript.*
22
+
23
+ @example
24
+ ```
25
+ type OnlyAcceptName = {name: string};
26
+
27
+ declare function onlyAcceptName(arguments_: OnlyAcceptName): void;
28
+
29
+ // TypeScript complains about excess properties when an object literal is provided.
30
+ // @ts-expect-error
31
+ onlyAcceptName({name: 'name', id: 1});
32
+ // `id` is excess
33
+
34
+ // TypeScript does not complain about excess properties when the provided value is a variable (not an object literal).
35
+ const invalidInput = {name: 'name', id: 1};
36
+ onlyAcceptName(invalidInput); // No errors
37
+ ```
38
+
39
+ Having `Exact` allows TypeScript to reject excess properties.
40
+
41
+ @example
42
+ ```
43
+ import type {Exact} from 'type-fest';
44
+
45
+ type OnlyAcceptName = {name: string};
46
+
47
+ declare function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T): void;
48
+
49
+ const invalidInput = {name: 'name', id: 1};
50
+ // @ts-expect-error
51
+ onlyAcceptNameImproved(invalidInput); // Compilation error
52
+ ```
53
+
54
+ [Read more](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined)
55
+
56
+ @category Utilities
57
+ */
58
+ export type Exact<ParameterType, InputType> =
59
+ // Before distributing, check if the two types are equal and if so, return the parameter type immediately
60
+ IsEqual<ParameterType, InputType> extends true ? ParameterType
61
+ // If the parameter is a primitive, return it as is immediately to avoid it being converted to a complex type
62
+ : ParameterType extends Primitive ? ParameterType
63
+ // If the parameter is an unknown, return it as is immediately to avoid it being converted to a complex type
64
+ : IsUnknown<ParameterType> extends true ? unknown
65
+ // If the parameter is a Function, return it as is because this type is not capable of handling function, leave it to TypeScript
66
+ : ParameterType extends Function ? ParameterType
67
+ // Convert union of array to array of union: A[] & B[] => (A & B)[]
68
+ : ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
69
+ // In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray.
70
+ : ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
71
+ : ExactObject<ParameterType, InputType>;
72
+
73
+ export {};
@@ -0,0 +1,112 @@
1
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
2
+ import type {IsEqual} from './is-equal.d.ts';
3
+
4
+ /**
5
+ Filter out keys from an object.
6
+
7
+ Returns `never` if `Exclude` is strictly equal to `Key`.
8
+ Returns `never` if `Key` extends `Exclude`.
9
+ Returns `Key` otherwise.
10
+
11
+ @example
12
+ ```
13
+ type Filtered = Filter<'foo', 'foo'>;
14
+ //=> never
15
+ ```
16
+
17
+ @example
18
+ ```
19
+ type Filtered = Filter<'bar', string>;
20
+ //=> never
21
+ ```
22
+
23
+ @example
24
+ ```
25
+ type Filtered = Filter<'bar', 'foo'>;
26
+ //=> 'bar'
27
+ ```
28
+
29
+ @see {Except}
30
+ */
31
+ type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
32
+
33
+ export type ExceptOptions = {
34
+ /**
35
+ Disallow assigning non-specified properties.
36
+
37
+ Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`.
38
+
39
+ @default false
40
+ */
41
+ requireExactProps?: boolean;
42
+ };
43
+
44
+ type DefaultExceptOptions = {
45
+ requireExactProps: false;
46
+ };
47
+
48
+ /**
49
+ Create a type from an object type without certain keys.
50
+
51
+ We recommend setting the `requireExactProps` option to `true`.
52
+
53
+ This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically.
54
+
55
+ This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)).
56
+
57
+ @example
58
+ ```
59
+ import type {Except} from 'type-fest';
60
+
61
+ type Foo = {
62
+ a: number;
63
+ b: string;
64
+ };
65
+
66
+ type FooWithoutA = Except<Foo, 'a'>;
67
+ //=> {b: string}
68
+
69
+ // @ts-expect-error
70
+ const fooWithoutA: FooWithoutA = {a: 1, b: '2'};
71
+ // errors: 'a' does not exist in type '{ b: string; }'
72
+
73
+ type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;
74
+ //=> {a: number} & Partial<Record<'b', never>>
75
+
76
+ // @ts-expect-error
77
+ const fooWithoutB: FooWithoutB = {a: 1, b: '2'};
78
+ // errors at 'b': Type 'string' is not assignable to type 'undefined'.
79
+
80
+ // The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures.
81
+
82
+ // Consider the following example:
83
+
84
+ type UserData = {
85
+ [metadata: string]: string;
86
+ email: string;
87
+ name: string;
88
+ role: 'admin' | 'user';
89
+ };
90
+
91
+ // `Omit` clearly doesn't behave as expected in this case:
92
+ type PostPayload = Omit<UserData, 'email'>;
93
+ //=> {[x: string]: string; [x: number]: string}
94
+
95
+ // In situations like this, `Except` works better.
96
+ // It simply removes the `email` key while preserving all the other keys.
97
+ type PostPayloadFixed = Except<UserData, 'email'>;
98
+ //=> {[x: string]: string; name: string; role: 'admin' | 'user'}
99
+ ```
100
+
101
+ @category Object
102
+ */
103
+ export type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> =
104
+ _Except<ObjectType, KeysType, ApplyDefaultOptions<ExceptOptions, DefaultExceptOptions, Options>>;
105
+
106
+ type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = {
107
+ [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
108
+ } & (Options['requireExactProps'] extends true
109
+ ? Partial<Record<KeysType, never>>
110
+ : {});
111
+
112
+ export {};
@@ -0,0 +1,40 @@
1
+ import type {SplitOnRestElement} from './split-on-rest-element.d.ts';
2
+ import type {IsArrayReadonly} from './internal/array.d.ts';
3
+ import type {UnknownArray} from './unknown-array.d.ts';
4
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
5
+
6
+ /**
7
+ Create a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed.
8
+
9
+ @example
10
+ ```
11
+ import type {ExcludeRestElement} from 'type-fest';
12
+
13
+ type T1 = ExcludeRestElement<[number, ...string[], string, 'foo']>;
14
+ //=> [number, string, 'foo']
15
+
16
+ type T2 = ExcludeRestElement<[...boolean[], string]>;
17
+ //=> [string]
18
+
19
+ type T3 = ExcludeRestElement<[...Array<'foo'>, true]>;
20
+ //=> [true]
21
+
22
+ type T4 = ExcludeRestElement<[number, string]>;
23
+ //=> [number, string]
24
+ ```
25
+
26
+ @see {@link ExtractRestElement}
27
+ @see {@link SplitOnRestElement}
28
+ @category Array
29
+ */
30
+ export type ExcludeRestElement<Array_ extends UnknownArray> = IfNotAnyOrNever<Array_,
31
+ SplitOnRestElement<Array_> extends infer Result
32
+ ? Result extends readonly UnknownArray[]
33
+ ? IsArrayReadonly<Array_> extends true
34
+ ? Readonly<[...Result[0], ...Result[2]]>
35
+ : [...Result[0], ...Result[2]]
36
+ : never
37
+ : never
38
+ >;
39
+
40
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ A stricter version of {@link Exclude<T, U>} that ensures every member of `U` can successfully exclude something from `T`.
3
+
4
+ For example, `ExcludeStrict<string | number | boolean, number | bigint>` will error because `bigint` cannot exclude anything from `string | number | boolean`.
5
+
6
+ @example
7
+ ```
8
+ // Valid Examples
9
+ import type {ExcludeStrict} from 'type-fest';
10
+
11
+ type Example1 = ExcludeStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>;
12
+ //=> {status: 'error'; error: string}
13
+
14
+ type Example2 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>;
15
+ //=> 'm' | 'l' | 'xl'
16
+
17
+ type Example3 = ExcludeStrict<{x: number; y: number} | [number, number], unknown[]>;
18
+ //=> {x: number; y: number}
19
+ ```
20
+
21
+ @example
22
+ ```
23
+ // Invalid Examples
24
+ import type {ExcludeStrict} from 'type-fest';
25
+
26
+ // `'xxl'` cannot exclude anything from `'xs' | 's' | 'm' | 'l' | 'xl'`
27
+ // @ts-expect-error
28
+ type Example1 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>;
29
+ // ~~~~~~~~~~~~
30
+ // Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'.
31
+
32
+ // `unknown[]` cannot exclude anything from `{x: number; y: number} | {x: string; y: string}`
33
+ // @ts-expect-error
34
+ type Example2 = ExcludeStrict<{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 ExcludeStrict<
42
+ T,
43
+ U extends [U] extends [
44
+ // Ensure every member of `U` excludes something from `T`
45
+ U extends unknown ? ([T] extends [Exclude<T, U>] ? never : U) : never,
46
+ ]
47
+ ? unknown
48
+ : never,
49
+ > = Exclude<T, U>;
50
+
51
+ export {};