type-fest 4.41.0 → 5.0.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 (156) hide show
  1. package/index.d.ts +174 -153
  2. package/package.json +20 -44
  3. package/readme.md +45 -68
  4. package/source/all-extend.d.ts +115 -0
  5. package/source/all-union-fields.d.ts +12 -12
  6. package/source/and.d.ts +60 -8
  7. package/source/array-slice.d.ts +11 -11
  8. package/source/array-splice.d.ts +4 -4
  9. package/source/array-tail.d.ts +40 -48
  10. package/source/arrayable.d.ts +2 -2
  11. package/source/asyncify.d.ts +1 -1
  12. package/source/basic.d.ts +1 -33
  13. package/source/camel-case.d.ts +6 -6
  14. package/source/camel-cased-properties-deep.d.ts +7 -7
  15. package/source/camel-cased-properties.d.ts +4 -4
  16. package/source/characters.d.ts +60 -0
  17. package/source/conditional-except.d.ts +4 -4
  18. package/source/conditional-keys.d.ts +33 -19
  19. package/source/conditional-pick-deep.d.ts +9 -9
  20. package/source/conditional-pick.d.ts +3 -3
  21. package/source/conditional-simplify-deep.d.ts +71 -0
  22. package/source/conditional-simplify.d.ts +36 -20
  23. package/source/delimiter-case.d.ts +9 -12
  24. package/source/delimiter-cased-properties-deep.d.ts +4 -4
  25. package/source/delimiter-cased-properties.d.ts +3 -3
  26. package/source/distributed-omit.d.ts +1 -1
  27. package/source/distributed-pick.d.ts +1 -1
  28. package/source/enforce-optional.d.ts +1 -1
  29. package/source/entries.d.ts +1 -1
  30. package/source/exact.d.ts +6 -6
  31. package/source/except.d.ts +2 -2
  32. package/source/exclude-strict.d.ts +45 -0
  33. package/source/extends-strict.d.ts +42 -0
  34. package/source/extract-strict.d.ts +45 -0
  35. package/source/find-global-type.d.ts +1 -1
  36. package/source/fixed-length-array.d.ts +2 -2
  37. package/source/get.d.ts +15 -14
  38. package/source/globals/index.d.ts +1 -0
  39. package/source/{observable-like.d.ts → globals/observable-like.d.ts} +10 -0
  40. package/source/greater-than-or-equal.d.ts +1 -1
  41. package/source/greater-than.d.ts +9 -9
  42. package/source/has-optional-keys.d.ts +1 -1
  43. package/source/has-readonly-keys.d.ts +1 -1
  44. package/source/has-required-keys.d.ts +1 -1
  45. package/source/has-writable-keys.d.ts +1 -1
  46. package/source/if-any.d.ts +3 -1
  47. package/source/if-empty-object.d.ts +3 -1
  48. package/source/if-never.d.ts +3 -1
  49. package/source/if-null.d.ts +3 -1
  50. package/source/if-unknown.d.ts +3 -1
  51. package/source/if.d.ts +65 -0
  52. package/source/includes.d.ts +1 -1
  53. package/source/int-closed-range.d.ts +2 -2
  54. package/source/int-range.d.ts +6 -4
  55. package/source/internal/array.d.ts +54 -22
  56. package/source/internal/characters.d.ts +0 -4
  57. package/source/internal/index.d.ts +8 -8
  58. package/source/internal/keys.d.ts +24 -23
  59. package/source/internal/numeric.d.ts +45 -15
  60. package/source/internal/object.d.ts +58 -29
  61. package/source/internal/string.d.ts +4 -14
  62. package/source/internal/tuple.d.ts +4 -4
  63. package/source/internal/type.d.ts +34 -43
  64. package/source/is-any.d.ts +0 -4
  65. package/source/is-float.d.ts +1 -1
  66. package/source/is-integer.d.ts +4 -4
  67. package/source/is-literal.d.ts +44 -28
  68. package/source/is-lowercase.d.ts +36 -0
  69. package/source/is-nullable.d.ts +28 -0
  70. package/source/is-optional-key-of.d.ts +49 -0
  71. package/source/is-optional.d.ts +26 -0
  72. package/source/is-readonly-key-of.d.ts +53 -0
  73. package/source/is-required-key-of.d.ts +49 -0
  74. package/source/is-tuple.d.ts +15 -14
  75. package/source/is-undefined.d.ts +20 -0
  76. package/source/is-union.d.ts +37 -0
  77. package/source/is-unknown.d.ts +1 -1
  78. package/source/is-uppercase.d.ts +36 -0
  79. package/source/is-writable-key-of.d.ts +49 -0
  80. package/source/json-value.d.ts +31 -0
  81. package/source/jsonifiable.d.ts +1 -1
  82. package/source/jsonify.d.ts +18 -14
  83. package/source/kebab-case.d.ts +3 -3
  84. package/source/kebab-cased-properties-deep.d.ts +4 -4
  85. package/source/kebab-cased-properties.d.ts +4 -4
  86. package/source/{string-key-of.d.ts → key-as-string.d.ts} +5 -5
  87. package/source/keys-of-union.d.ts +1 -1
  88. package/source/less-than-or-equal.d.ts +1 -1
  89. package/source/less-than.d.ts +1 -1
  90. package/source/literal-to-primitive-deep.d.ts +2 -2
  91. package/source/literal-union.d.ts +1 -1
  92. package/source/merge-deep.d.ts +43 -34
  93. package/source/merge.d.ts +5 -5
  94. package/source/multidimensional-array.d.ts +2 -2
  95. package/source/multidimensional-readonly-array.d.ts +2 -2
  96. package/source/non-empty-object.d.ts +2 -2
  97. package/source/numeric.d.ts +4 -4
  98. package/source/omit-deep.d.ts +11 -11
  99. package/source/opaque.d.ts +1 -1
  100. package/source/optional-keys-of.d.ts +10 -5
  101. package/source/or.d.ts +67 -7
  102. package/source/override-properties.d.ts +1 -1
  103. package/source/package-json.d.ts +78 -78
  104. package/source/partial-deep.d.ts +22 -21
  105. package/source/partial-on-undefined-deep.d.ts +5 -4
  106. package/source/pascal-case.d.ts +13 -6
  107. package/source/pascal-cased-properties-deep.d.ts +11 -3
  108. package/source/pascal-cased-properties.d.ts +7 -3
  109. package/source/paths.d.ts +42 -39
  110. package/source/pick-deep.d.ts +6 -6
  111. package/source/readonly-deep.d.ts +2 -2
  112. package/source/readonly-keys-of.d.ts +10 -4
  113. package/source/remove-prefix.d.ts +128 -0
  114. package/source/replace.d.ts +1 -1
  115. package/source/require-all-or-none.d.ts +8 -7
  116. package/source/require-at-least-one.d.ts +10 -9
  117. package/source/require-exactly-one.d.ts +8 -7
  118. package/source/require-one-or-none.d.ts +9 -8
  119. package/source/required-deep.d.ts +26 -32
  120. package/source/required-keys-of.d.ts +4 -4
  121. package/source/schema.d.ts +74 -74
  122. package/source/screaming-snake-case.d.ts +4 -4
  123. package/source/set-field-type.d.ts +2 -2
  124. package/source/set-non-nullable-deep.d.ts +6 -6
  125. package/source/set-optional.d.ts +11 -5
  126. package/source/set-parameter-type.d.ts +7 -7
  127. package/source/set-readonly.d.ts +12 -9
  128. package/source/set-required-deep.d.ts +12 -12
  129. package/source/set-required.d.ts +15 -8
  130. package/source/set-return-type.d.ts +1 -1
  131. package/source/shared-union-fields-deep.d.ts +10 -10
  132. package/source/shared-union-fields.d.ts +5 -4
  133. package/source/simplify-deep.d.ts +3 -3
  134. package/source/single-key-object.d.ts +4 -3
  135. package/source/snake-case.d.ts +3 -3
  136. package/source/snake-cased-properties-deep.d.ts +4 -4
  137. package/source/snake-cased-properties.d.ts +4 -4
  138. package/source/split.d.ts +9 -9
  139. package/source/spread.d.ts +3 -3
  140. package/source/string-repeat.d.ts +2 -2
  141. package/source/string-slice.d.ts +3 -3
  142. package/source/structured-cloneable.d.ts +25 -25
  143. package/source/subtract.d.ts +3 -3
  144. package/source/sum.d.ts +3 -3
  145. package/source/tagged-union.d.ts +1 -1
  146. package/source/tagged.d.ts +3 -1
  147. package/source/trim.d.ts +1 -1
  148. package/source/tsconfig-json.d.ts +2 -1
  149. package/source/tuple-to-object.d.ts +5 -4
  150. package/source/undefined-on-partial-deep.d.ts +1 -1
  151. package/source/union-to-tuple.d.ts +2 -2
  152. package/source/value-of.d.ts +1 -1
  153. package/source/words.d.ts +5 -5
  154. package/source/writable-deep.d.ts +1 -1
  155. package/source/writable-keys-of.d.ts +5 -6
  156. package/source/writable.d.ts +4 -4
package/source/basic.d.ts CHANGED
@@ -16,7 +16,7 @@ Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/Jav
16
16
  export type Constructor<T, Arguments extends unknown[] = any[]> = new(...arguments_: Arguments) => T;
17
17
 
18
18
  /**
19
- Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes).
19
+ Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/2/classes.html#abstract-classes-and-members).
20
20
 
21
21
  @category Class
22
22
 
@@ -34,35 +34,3 @@ Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/relea
34
34
  @category Class
35
35
  */
36
36
  export type AbstractConstructor<T, Arguments extends unknown[] = any[]> = abstract new(...arguments_: Arguments) => T;
37
-
38
- /**
39
- Matches a JSON object.
40
-
41
- This type can be useful to enforce some input to be JSON-compatible or as a super-type to be extended from. Don't use this as a direct return type as the user would have to double-cast it: `jsonObject as unknown as CustomResponse`. Instead, you could extend your CustomResponse type from it to ensure your type only uses JSON-compatible types: `interface CustomResponse extends JsonObject { … }`.
42
-
43
- @category JSON
44
- */
45
- export type JsonObject = {[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined};
46
-
47
- /**
48
- Matches a JSON array.
49
-
50
- @category JSON
51
- */
52
- export type JsonArray = JsonValue[] | readonly JsonValue[];
53
-
54
- /**
55
- Matches any valid JSON primitive value.
56
-
57
- @category JSON
58
- */
59
- export type JsonPrimitive = string | number | boolean | null;
60
-
61
- /**
62
- Matches any valid JSON value.
63
-
64
- @see `Jsonify` if you need to transform a type to one that is assignable to `JsonValue`.
65
-
66
- @category JSON
67
- */
68
- export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
@@ -1,5 +1,5 @@
1
- import type {ApplyDefaultOptions} from './internal';
2
- import type {Words} from './words';
1
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
2
+ import type {Words} from './words.d.ts';
3
3
 
4
4
  /**
5
5
  CamelCase options.
@@ -10,13 +10,13 @@ export type CamelCaseOptions = {
10
10
  /**
11
11
  Whether to preserved consecutive uppercase letter.
12
12
 
13
- @default true
13
+ @default false
14
14
  */
15
15
  preserveConsecutiveUppercase?: boolean;
16
16
  };
17
17
 
18
18
  export type DefaultCamelCaseOptions = {
19
- preserveConsecutiveUppercase: true;
19
+ preserveConsecutiveUppercase: false;
20
20
  };
21
21
 
22
22
  /**
@@ -83,7 +83,7 @@ export type CamelCase<Type, Options extends CamelCaseOptions = {}> = Type extend
83
83
  ? string extends Type
84
84
  ? Type
85
85
  : Uncapitalize<CamelCaseFromArray<
86
- Words<Type extends Uppercase<Type> ? Lowercase<Type> : Type>,
87
- ApplyDefaultOptions<CamelCaseOptions, DefaultCamelCaseOptions, Options>
86
+ Words<Type extends Uppercase<Type> ? Lowercase<Type> : Type>,
87
+ ApplyDefaultOptions<CamelCaseOptions, DefaultCamelCaseOptions, Options>
88
88
  >>
89
89
  : Type;
@@ -1,6 +1,6 @@
1
- import type {CamelCase, CamelCaseOptions, DefaultCamelCaseOptions} from './camel-case';
2
- import type {ApplyDefaultOptions, NonRecursiveType} from './internal';
3
- import type {UnknownArray} from './unknown-array';
1
+ import type {CamelCase, CamelCaseOptions, DefaultCamelCaseOptions} from './camel-case.d.ts';
2
+ import type {ApplyDefaultOptions, NonRecursiveType} from './internal/index.d.ts';
3
+ import type {UnknownArray} from './unknown-array.d.ts';
4
4
 
5
5
  /**
6
6
  Convert object properties to camel case recursively.
@@ -41,10 +41,10 @@ const result: CamelCasedPropertiesDeep<UserWithFriends> = {
41
41
  ],
42
42
  };
43
43
 
44
- const preserveConsecutiveUppercase: CamelCasedPropertiesDeep<{fooBAR: { fooBARBiz: [{ fooBARBaz: string }] }}, {preserveConsecutiveUppercase: false}> = {
45
- fooBar: {
46
- fooBarBiz: [{
47
- fooBarBaz: 'string',
44
+ const preserveConsecutiveUppercase: CamelCasedPropertiesDeep<{fooBAR: {fooBARBiz: [{fooBARBaz: string}]}}, {preserveConsecutiveUppercase: true}> = {
45
+ fooBAR: {
46
+ fooBARBiz: [{
47
+ fooBARBaz: 'string',
48
48
  }],
49
49
  },
50
50
  };
@@ -1,5 +1,5 @@
1
- import type {CamelCase, CamelCaseOptions, DefaultCamelCaseOptions} from './camel-case';
2
- import type {ApplyDefaultOptions} from './internal';
1
+ import type {CamelCase, CamelCaseOptions, DefaultCamelCaseOptions} from './camel-case.d.ts';
2
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
3
3
 
4
4
  /**
5
5
  Convert object properties to camel case but not recursively.
@@ -23,8 +23,8 @@ const result: CamelCasedProperties<User> = {
23
23
  userName: 'Tom',
24
24
  };
25
25
 
26
- const preserveConsecutiveUppercase: CamelCasedProperties<{fooBAR: string}, {preserveConsecutiveUppercase: false}> = {
27
- fooBar: 'string',
26
+ const preserveConsecutiveUppercase: CamelCasedProperties<{fooBAR: string}, {preserveConsecutiveUppercase: true}> = {
27
+ fooBAR: 'string',
28
28
  };
29
29
  ```
30
30
 
@@ -0,0 +1,60 @@
1
+ /**
2
+ Matches any uppercase letter in the basic Latin alphabet (A-Z).
3
+
4
+ @example
5
+ ```
6
+ import type {UppercaseLetter} from 'type-fest';
7
+
8
+ const a: UppercaseLetter = 'A'; // Valid
9
+ const b: UppercaseLetter = 'a'; // Invalid
10
+ const c: UppercaseLetter = 'AB'; // Invalid
11
+ ```
12
+
13
+ @category Type
14
+ */
15
+ export type UppercaseLetter = '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';
16
+
17
+ /**
18
+ Matches any lowercase letter in the basic Latin alphabet (a-z).
19
+
20
+ @example
21
+ ```
22
+ import type {LowercaseLetter} from 'type-fest';
23
+
24
+ const a: LowercaseLetter = 'a'; // Valid
25
+ const b: LowercaseLetter = 'A'; // Invalid
26
+ ```
27
+
28
+ @category Type
29
+ */
30
+ export type LowercaseLetter = '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';
31
+
32
+ /**
33
+ Matches any digit as a string ('0'-'9').
34
+
35
+ @example
36
+ ```
37
+ import type {DigitCharacter} from 'type-fest';
38
+
39
+ const a: DigitCharacter = '0'; // Valid
40
+ const b: DigitCharacter = 0; // Invalid
41
+ ```
42
+
43
+ @category Type
44
+ */
45
+ export type DigitCharacter = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
46
+
47
+ /**
48
+ Matches any lowercase letter (a-z), uppercase letter (A-Z), or digit ('0'-'9') in the basic Latin alphabet.
49
+
50
+ @example
51
+ ```
52
+ import type {Alphanumeric} from 'type-fest';
53
+
54
+ const a: Alphanumeric = 'A'; // Valid
55
+ const b: Alphanumeric = '#'; // Invalid
56
+ ```
57
+
58
+ @category Type
59
+ */
60
+ export type Alphanumeric = LowercaseLetter | UppercaseLetter | DigitCharacter;
@@ -1,5 +1,5 @@
1
- import type {Except} from './except';
2
- import type {ConditionalKeys} from './conditional-keys';
1
+ import type {Except} from './except.d.ts';
2
+ import type {ConditionalKeys} from './conditional-keys.d.ts';
3
3
 
4
4
  /**
5
5
  Exclude keys from a shape that matches the given `Condition`.
@@ -40,6 +40,6 @@ type NonStringKeysOnly = ConditionalExcept<Example, string>;
40
40
  @category Object
41
41
  */
42
42
  export type ConditionalExcept<Base, Condition> = Except<
43
- Base,
44
- ConditionalKeys<Base, Condition>
43
+ Base,
44
+ ConditionalKeys<Base, Condition>
45
45
  >;
@@ -1,4 +1,7 @@
1
- import type {IfNever} from './if-never';
1
+ import type {ExtendsStrict} from './extends-strict.d.ts';
2
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
3
+ import type {TupleToObject} from './tuple-to-object.d.ts';
4
+ import type {UnknownArray} from './unknown-array.d.ts';
2
5
 
3
6
  /**
4
7
  Extract the keys from a type where the value type of the key extends the given `Condition`.
@@ -9,39 +12,50 @@ Internally this is used for the `ConditionalPick` and `ConditionalExcept` types.
9
12
  ```
10
13
  import type {ConditionalKeys} from 'type-fest';
11
14
 
12
- interface Example {
15
+ type Example = {
13
16
  a: string;
14
17
  b: string | number;
15
18
  c?: string;
16
19
  d: {};
17
- }
20
+ };
18
21
 
19
22
  type StringKeysOnly = ConditionalKeys<Example, string>;
20
23
  //=> 'a'
21
24
  ```
22
25
 
23
- To support partial types, make sure your `Condition` is a union of undefined (for example, `string | undefined`) as demonstrated below.
26
+ Note: To extract optional keys, make sure your `Condition` is a union of `undefined` (for example, `string | undefined`) as demonstrated below.
24
27
 
25
28
  @example
26
29
  ```
27
30
  import type {ConditionalKeys} from 'type-fest';
28
31
 
29
- type StringKeysAndUndefined = ConditionalKeys<Example, string | undefined>;
30
- //=> 'a' | 'c'
32
+ type StringKeysAndUndefined = ConditionalKeys<{a?: string}, string | undefined>;
33
+ //=> 'a'
34
+
35
+ type NoMatchingKeys = ConditionalKeys<{a?: string}, string>;
36
+ //=> never
37
+ ```
38
+
39
+ You can also extract array indices whose value match the specified condition, as shown below:
40
+ ```
41
+ import type {ConditionalKeys} from 'type-fest';
42
+
43
+ type StringValueIndices = ConditionalKeys<[string, number, string], string>;
44
+ //=> '0' | '2'
45
+
46
+ type NumberValueIndices = ConditionalKeys<[string, number?, string?], number | undefined>;
47
+ //=> '1'
31
48
  ```
32
49
 
33
50
  @category Object
34
51
  */
35
- export type ConditionalKeys<Base, Condition> =
36
- {
37
- // Map through all the keys of the given base type.
38
- [Key in keyof Base]-?:
39
- // Pick only keys with types extending the given `Condition` type.
40
- Base[Key] extends Condition
41
- // Retain this key
42
- // If the value for the key extends never, only include it if `Condition` also extends never
43
- ? IfNever<Base[Key], IfNever<Condition, Key, never>, Key>
44
- // Discard this key since the condition fails.
45
- : never;
46
- // Convert the produced object into a union type of the keys which passed the conditional test.
47
- }[keyof Base];
52
+ export type ConditionalKeys<Base, Condition> = (Base extends UnknownArray ? TupleToObject<Base> : Base) extends infer _Base // Remove non-numeric keys from arrays
53
+ ? IfNotAnyOrNever<_Base, _ConditionalKeys<_Base, Condition>, keyof _Base>
54
+ : never;
55
+
56
+ type _ConditionalKeys<Base, Condition> = keyof {
57
+ [
58
+ Key in (keyof Base & {}) as // `& {}` prevents homomorphism
59
+ ExtendsStrict<Base[Key], Condition> extends true ? Key : never
60
+ ]: never
61
+ };
@@ -1,9 +1,9 @@
1
- import type {IsEqual} from './is-equal';
2
- import type {ConditionalExcept} from './conditional-except';
3
- import type {ConditionalSimplifyDeep} from './conditional-simplify';
4
- import type {UnknownRecord} from './unknown-record';
5
- import type {EmptyObject} from './empty-object';
6
- import type {ApplyDefaultOptions, IsPlainObject} from './internal';
1
+ import type {IsEqual} from './is-equal.d.ts';
2
+ import type {ConditionalExcept} from './conditional-except.d.ts';
3
+ import type {ConditionalSimplifyDeep} from './conditional-simplify-deep.d.ts';
4
+ import type {UnknownRecord} from './unknown-record.d.ts';
5
+ import type {EmptyObject} from './empty-object.d.ts';
6
+ import type {ApplyDefaultOptions, IsPlainObject} from './internal/index.d.ts';
7
7
 
8
8
  /**
9
9
  Used to mark properties that should be excluded.
@@ -100,9 +100,9 @@ export type ConditionalPickDeep<
100
100
  Condition,
101
101
  Options extends ConditionalPickDeepOptions = {},
102
102
  > = _ConditionalPickDeep<
103
- Type,
104
- Condition,
105
- ApplyDefaultOptions<ConditionalPickDeepOptions, DefaultConditionalPickDeepOptions, Options>
103
+ Type,
104
+ Condition,
105
+ ApplyDefaultOptions<ConditionalPickDeepOptions, DefaultConditionalPickDeepOptions, Options>
106
106
  >;
107
107
 
108
108
  type _ConditionalPickDeep<
@@ -1,4 +1,4 @@
1
- import type {ConditionalKeys} from './conditional-keys';
1
+ import type {ConditionalKeys} from './conditional-keys.d.ts';
2
2
 
3
3
  /**
4
4
  Pick keys from the shape that matches the given `Condition`.
@@ -39,6 +39,6 @@ type StringKeysOnly = ConditionalPick<Example, string>;
39
39
  @category Object
40
40
  */
41
41
  export type ConditionalPick<Base, Condition> = Pick<
42
- Base,
43
- ConditionalKeys<Base, Condition>
42
+ Base,
43
+ ConditionalKeys<Base, Condition>
44
44
  >;
@@ -0,0 +1,71 @@
1
+ /**
2
+ Recursively simplifies a type while including and/or excluding certain types from being simplified.
3
+
4
+ @example
5
+ ```
6
+ import type {ConditionalSimplifyDeep} from 'type-fest';
7
+
8
+ type TypeA = {
9
+ foo: {
10
+ a: string;
11
+ };
12
+ };
13
+
14
+ type TypeB = {
15
+ foo: {
16
+ b: string;
17
+ };
18
+ };
19
+
20
+ type SimplifyDeepTypeAB = ConditionalSimplifyDeep<TypeA & TypeB, never, object>;
21
+ //=> {foo: {a: string; b: string}}
22
+ ```
23
+
24
+ @example
25
+ ```
26
+ import type {ConditionalSimplifyDeep} from 'type-fest';
27
+
28
+ type SomeComplexType1 = {
29
+ a1: string;
30
+ b1: number;
31
+ c1: boolean;
32
+ };
33
+
34
+ type SomeComplexType2 = {
35
+ a2: string;
36
+ b2: number;
37
+ c2: boolean;
38
+ };
39
+
40
+ type TypeA = {
41
+ foo: {
42
+ a: string;
43
+ complexType: SomeComplexType1;
44
+ };
45
+ };
46
+
47
+ type TypeB = {
48
+ foo: {
49
+ b: string;
50
+ complexType: SomeComplexType2;
51
+ };
52
+ };
53
+
54
+ type SimplifyDeepTypeAB = ConditionalSimplifyDeep<TypeA & TypeB, SomeComplexType1 | SomeComplexType2, object>;
55
+ //=> {
56
+ // foo: {
57
+ // a: string;
58
+ // b: string;
59
+ // complexType: SomeComplexType1 & SomeComplexType2;
60
+ // };
61
+ // }
62
+ ```
63
+
64
+ @see SimplifyDeep
65
+ @category Object
66
+ */
67
+ export type ConditionalSimplifyDeep<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
68
+ ? Type
69
+ : Type extends IncludeType
70
+ ? {[TypeKey in keyof Type]: ConditionalSimplifyDeep<Type[TypeKey], ExcludeType, IncludeType>}
71
+ : Type;
@@ -1,32 +1,48 @@
1
1
  /**
2
- Simplifies a type while including and/or excluding certain types from being simplified. Useful to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
2
+ Simplifies a type while including and/or excluding certain types from being simplified.
3
3
 
4
- This type is **experimental** and was introduced as a result of this {@link https://github.com/sindresorhus/type-fest/issues/436 issue}. It should be used with caution.
4
+ Useful to improve type hints shown in editors. And also to transform an `interface` into a `type` to aid with assignability.
5
5
 
6
- @internal
7
- @experimental
8
- @see Simplify
9
- @category Object
10
- */
11
- export type ConditionalSimplify<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
12
- ? Type
13
- : Type extends IncludeType
14
- ? {[TypeKey in keyof Type]: Type[TypeKey]}
15
- : Type;
6
+ @example
7
+ ```
8
+ import type {ConditionalSimplify} from 'type-fest';
16
9
 
17
- /**
18
- Recursively simplifies a type while including and/or excluding certain types from being simplified.
10
+ type TypeA = {
11
+ a: string;
12
+ };
19
13
 
20
- This type is **experimental** and was introduced as a result of this {@link https://github.com/sindresorhus/type-fest/issues/436 issue}. It should be used with caution.
14
+ type TypeB = {
15
+ b: string;
16
+ };
21
17
 
22
- See {@link ConditionalSimplify} for usages and examples.
18
+ type TypeAB = TypeA & TypeB;
19
+ //=> TypeA & TypeB
23
20
 
24
- @internal
25
- @experimental
21
+ type SimplifyTypeAB = ConditionalSimplify<TypeAB, never, object>;
22
+ //=> {a: string; b: string}
23
+ ```
24
+
25
+ @example
26
+ ```
27
+ import type {ConditionalSimplify} from 'type-fest';
28
+
29
+ type Simplify<T> = ConditionalSimplify<T, Set<unknown> | Map<unknown, unknown> | unknown[], object>;
30
+
31
+ type A = Simplify<Set<number> & Set<string>>;
32
+ //=> Set<number> & Set<string>
33
+
34
+ type B = Simplify<Map<number, number> & Map<string, string>>;
35
+ //=> Map<number, number> & Map<string, string>
36
+
37
+ type C = Simplify<{a: number} & {b: string}>;
38
+ //=> {a: number; b: string}
39
+ ```
40
+
41
+ @see ConditionalSimplifyDeep
26
42
  @category Object
27
43
  */
28
- export type ConditionalSimplifyDeep<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
44
+ export type ConditionalSimplify<Type, ExcludeType = never, IncludeType = unknown> = Type extends ExcludeType
29
45
  ? Type
30
46
  : Type extends IncludeType
31
- ? {[TypeKey in keyof Type]: ConditionalSimplifyDeep<Type[TypeKey], ExcludeType, IncludeType>}
47
+ ? {[TypeKey in keyof Type]: Type[TypeKey]}
32
48
  : Type;
@@ -1,7 +1,8 @@
1
- import type {ApplyDefaultOptions, AsciiPunctuation, StartsWith} from './internal';
2
- import type {IsStringLiteral} from './is-literal';
3
- import type {Merge} from './merge';
4
- import type {DefaultWordsOptions, Words, WordsOptions} from './words';
1
+ import type {ApplyDefaultOptions, AsciiPunctuation, StartsWith} from './internal/index.d.ts';
2
+ import type {IsStringLiteral} from './is-literal.d.ts';
3
+ import type {Merge} from './merge.d.ts';
4
+ import type {RemovePrefix} from './remove-prefix.d.ts';
5
+ import type {DefaultWordsOptions, Words, WordsOptions} from './words.d.ts';
5
6
 
6
7
  export type DefaultDelimiterCaseOptions = Merge<DefaultWordsOptions, {splitOnNumbers: false}>;
7
8
 
@@ -21,10 +22,6 @@ type DelimiterCaseFromArray<
21
22
  }${FirstWord}`>
22
23
  : OutputString;
23
24
 
24
- type RemoveFirstLetter<S extends string> = S extends `${infer _}${infer Rest}`
25
- ? Rest
26
- : '';
27
-
28
25
  /**
29
26
  Convert a string literal to a custom string delimiter casing.
30
27
 
@@ -71,8 +68,8 @@ export type DelimiterCase<
71
68
  > = Value extends string
72
69
  ? IsStringLiteral<Value> extends false
73
70
  ? Value
74
- : Lowercase<RemoveFirstLetter<DelimiterCaseFromArray<
75
- Words<Value, ApplyDefaultOptions<WordsOptions, DefaultDelimiterCaseOptions, Options>>,
76
- Delimiter
77
- >>>
71
+ : Lowercase<RemovePrefix<DelimiterCaseFromArray<
72
+ Words<Value, ApplyDefaultOptions<WordsOptions, DefaultDelimiterCaseOptions, Options>>,
73
+ Delimiter
74
+ >, string, {strict: false}>>
78
75
  : Value;
@@ -1,7 +1,7 @@
1
- import type {DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case';
2
- import type {ApplyDefaultOptions, NonRecursiveType} from './internal';
3
- import type {UnknownArray} from './unknown-array';
4
- import type {WordsOptions} from './words';
1
+ import type {DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts';
2
+ import type {ApplyDefaultOptions, NonRecursiveType} from './internal/index.d.ts';
3
+ import type {UnknownArray} from './unknown-array.d.ts';
4
+ import type {WordsOptions} from './words.d.ts';
5
5
 
6
6
  /**
7
7
  Convert object properties to delimiter case recursively.
@@ -1,6 +1,6 @@
1
- import type {DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case';
2
- import type {ApplyDefaultOptions} from './internal';
3
- import type {WordsOptions} from './words';
1
+ import type {DefaultDelimiterCaseOptions, DelimiterCase} from './delimiter-case.d.ts';
2
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
3
+ import type {WordsOptions} from './words.d.ts';
4
4
 
5
5
  /**
6
6
  Convert object properties to delimiter case but not recursively.
@@ -1,4 +1,4 @@
1
- import type {KeysOfUnion} from './keys-of-union';
1
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
2
2
 
3
3
  /**
4
4
  Omits keys from a type, distributing the operation over a union.
@@ -1,4 +1,4 @@
1
- import type {KeysOfUnion} from './keys-of-union';
1
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
2
2
 
3
3
  /**
4
4
  Pick keys from a type, distributing the operation over a union.
@@ -1,4 +1,4 @@
1
- import type {Simplify} from './simplify';
1
+ import type {Simplify} from './simplify.d.ts';
2
2
 
3
3
  // Returns `never` if the key is optional otherwise return the key type.
4
4
  type RequiredFilter<Type, Key extends keyof Type> = undefined extends Type[Key]
@@ -1,4 +1,4 @@
1
- import type {ArrayEntry, MapEntry, ObjectEntry, SetEntry} from './entry';
1
+ import type {ArrayEntry, MapEntry, ObjectEntry, SetEntry} from './entry.d.ts';
2
2
 
3
3
  type ArrayEntries<BaseType extends readonly unknown[]> = Array<ArrayEntry<BaseType>>;
4
4
  type MapEntries<BaseType> = Array<MapEntry<BaseType>>;
package/source/exact.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type {ArrayElement, ObjectValue} from './internal';
2
- import type {IsEqual} from './is-equal';
3
- import type {KeysOfUnion} from './keys-of-union';
4
- import type {IsUnknown} from './is-unknown';
5
- import type {Primitive} from './primitive';
1
+ import type {ArrayElement, ObjectValue} from './internal/index.d.ts';
2
+ import type {IsEqual} from './is-equal.d.ts';
3
+ import type {KeysOfUnion} from './keys-of-union.d.ts';
4
+ import type {IsUnknown} from './is-unknown.d.ts';
5
+ import type {Primitive} from './primitive.d.ts';
6
6
 
7
7
  /**
8
8
  Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
@@ -10,7 +10,7 @@ Create a type from `ParameterType` and `InputType` and change keys exclusive to
10
10
  - Mark these excess keys as `never`.
11
11
  */
12
12
  type ExactObject<ParameterType, InputType> = {[Key in keyof ParameterType]: Exact<ParameterType[Key], ObjectValue<InputType, Key>>}
13
- & Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>;
13
+ & Record<Exclude<keyof InputType, KeysOfUnion<ParameterType>>, never>;
14
14
 
15
15
  /**
16
16
  Create a type that does not allow extra properties, meaning it only allows properties that are explicitly declared.
@@ -1,5 +1,5 @@
1
- import type {ApplyDefaultOptions} from './internal';
2
- import type {IsEqual} from './is-equal';
1
+ import type {ApplyDefaultOptions} from './internal/index.d.ts';
2
+ import type {IsEqual} from './is-equal.d.ts';
3
3
 
4
4
  /**
5
5
  Filter out keys from an object.
@@ -0,0 +1,45 @@
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
+
10
+ type Example1 = ExcludeStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>;
11
+ //=> {status: 'error'; error: string}
12
+
13
+ type Example2 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>;
14
+ //=> 'm' | 'l' | 'xl'
15
+
16
+ type Example3 = ExcludeStrict<{x: number; y: number} | [number, number], unknown[]>;
17
+ //=> {x: number; y: number}
18
+ ```
19
+
20
+ @example
21
+ ```
22
+ // Invalid Examples
23
+
24
+ // `'xxl'` cannot exclude anything from `'xs' | 's' | 'm' | 'l' | 'xl'`
25
+ type Example1 = ExcludeStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>;
26
+ // ~~~~~~~~~~~~
27
+ // Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'.
28
+
29
+ // `unknown[]` cannot exclude anything from `{x: number; y: number} | {x: string; y: string}`
30
+ type Example2 = ExcludeStrict<{x: number; y: number} | {x: string; y: string}, unknown[]>;
31
+ // ~~~~~~~~~
32
+ // Error: Type 'unknown[]' does not satisfy the constraint 'never'.
33
+ ```
34
+
35
+ @category Improved Built-in
36
+ */
37
+ export type ExcludeStrict<
38
+ T,
39
+ U extends [U] extends [
40
+ // Ensure every member of `U` excludes something from `T`
41
+ U extends unknown ? ([T] extends [Exclude<T, U>] ? never : U) : never,
42
+ ]
43
+ ? unknown
44
+ : never,
45
+ > = Exclude<T, U>;