type-fest 4.40.1 → 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 -152
  2. package/package.json +20 -44
  3. package/readme.md +46 -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 +37 -32
  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 +42 -25
  64. package/source/is-any.d.ts +0 -4
  65. package/source/is-float.d.ts +1 -3
  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 +6 -2
  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 +12 -2
  116. package/source/require-at-least-one.d.ts +16 -2
  117. package/source/require-exactly-one.d.ts +12 -0
  118. package/source/require-one-or-none.d.ts +13 -3
  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 +83 -0
  125. package/source/set-optional.d.ts +11 -6
  126. package/source/set-parameter-type.d.ts +7 -7
  127. package/source/set-readonly.d.ts +12 -10
  128. package/source/set-required-deep.d.ts +12 -12
  129. package/source/set-required.d.ts +15 -9
  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
@@ -1,6 +1,7 @@
1
- import type {IsAny} from '../is-any';
2
- import type {IsLiteral} from '../is-literal';
3
- import type {ToString} from './string';
1
+ import type {IsAny} from '../is-any.d.ts';
2
+ import type {IsLiteral} from '../is-literal.d.ts';
3
+ import type {IsUnknown} from '../is-unknown.d.ts';
4
+ import type {ToString} from './string.d.ts';
4
5
 
5
6
  // Returns `never` if the key or property is not jsonable without testing whether the property is required or optional otherwise return the key.
6
7
  type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
@@ -22,32 +23,32 @@ type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
22
23
  Returns the required keys.
23
24
  */
24
25
  export type FilterDefinedKeys<T extends object> = Exclude<
25
- {
26
- [Key in keyof T]: IsAny<T[Key]> extends true
27
- ? Key
28
- : undefined extends T[Key]
29
- ? never
30
- : T[Key] extends undefined
26
+ {
27
+ [Key in keyof T]: IsAny<T[Key]> extends true
28
+ ? Key
29
+ : IsUnknown<T[Key]> extends true ? Key : undefined extends T[Key]
31
30
  ? never
32
- : BaseKeyFilter<T, Key>;
33
- }[keyof T],
34
- undefined
31
+ : T[Key] extends undefined
32
+ ? never
33
+ : BaseKeyFilter<T, Key>;
34
+ }[keyof T],
35
+ undefined
35
36
  >;
36
37
 
37
38
  /**
38
39
  Returns the optional keys.
39
40
  */
40
41
  export type FilterOptionalKeys<T extends object> = Exclude<
41
- {
42
- [Key in keyof T]: IsAny<T[Key]> extends true
43
- ? never
44
- : undefined extends T[Key]
45
- ? T[Key] extends undefined
46
- ? never
47
- : BaseKeyFilter<T, Key>
48
- : never;
49
- }[keyof T],
50
- undefined
42
+ {
43
+ [Key in keyof T]: IsAny<T[Key]> extends true
44
+ ? never
45
+ : undefined extends T[Key]
46
+ ? T[Key] extends undefined
47
+ ? never
48
+ : BaseKeyFilter<T, Key>
49
+ : never;
50
+ }[keyof T],
51
+ undefined
51
52
  >;
52
53
 
53
54
  /**
@@ -63,7 +64,7 @@ export type LiteralKeyOf<T> = keyof {[K in keyof T as IsLiteral<K> extends true
63
64
  /**
64
65
  Get the exact version of the given `Key` in the given object `T`.
65
66
 
66
- Use-case: You known that a number key (e.g. 10) is in an object, but you don't know how it is defined in the object, as a string or as a number (e.g. 10 or '10'). You can use this type to get the exact version of the key. See the example.
67
+ Use-case: You know that a number key (e.g. 10) is in an object, but you don't know how it is defined in the object, as a string or as a number (e.g. 10 or '10'). You can use this type to get the exact version of the key. See the example.
67
68
 
68
69
  @example
69
70
  ```
@@ -1,7 +1,8 @@
1
- import type {IsNever} from '../is-never';
2
- import type {NegativeInfinity, PositiveInfinity} from '../numeric';
3
- import type {UnknownArray} from '../unknown-array';
4
- import type {StringToNumber} from './string';
1
+ import type {IsNever} from '../is-never.d.ts';
2
+ import type {Finite, NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
3
+ import type {UnknownArray} from '../unknown-array.d.ts';
4
+ import type {StringToNumber} from './string.d.ts';
5
+ import type {IsAnyOrNever} from './type.d.ts';
5
6
 
6
7
  /**
7
8
  Returns the absolute value of a given value.
@@ -33,19 +34,20 @@ type A = IsNumberLike<'1'>;
33
34
  type B = IsNumberLike<'-1.1'>;
34
35
  //=> true
35
36
 
36
- type C = IsNumberLike<1>;
37
+ type C = IsNumberLike<'5e-20'>;
37
38
  //=> true
38
39
 
39
- type D = IsNumberLike<'a'>;
40
+ type D = IsNumberLike<1>;
41
+ //=> true
42
+
43
+ type E = IsNumberLike<'a'>;
40
44
  //=> false
41
45
  */
42
46
  export type IsNumberLike<N> =
43
- N extends number ? true
44
- : N extends `${number}`
47
+ IsAnyOrNever<N> extends true ? N
48
+ : N extends number | `${number}`
45
49
  ? true
46
- : N extends `${number}.${number}`
47
- ? true
48
- : false;
50
+ : false;
49
51
 
50
52
  /**
51
53
  Returns the minimum number in the given union of numbers.
@@ -54,11 +56,25 @@ Note: Just supports numbers from 0 to 999.
54
56
 
55
57
  @example
56
58
  ```
57
- type A = UnionMin<3 | 1 | 2>;
59
+ type A = UnionMin<1 | 3 | 2>;
58
60
  //=> 1
61
+
62
+ type B = UnionMin<number>;
63
+ //=> number
64
+
65
+ type C = UnionMin<any>;
66
+ //=> any
67
+
68
+ type D = UnionMin<never>;
69
+ //=> never
59
70
  ```
60
71
  */
61
- export type UnionMin<N extends number> = InternalUnionMin<N>;
72
+ export type UnionMin<N extends number> =
73
+ IsAnyOrNever<N> extends true ? N
74
+ : number extends N ? number
75
+ : NegativeInfinity extends N ? NegativeInfinity
76
+ : [N] extends [PositiveInfinity] ? PositiveInfinity
77
+ : InternalUnionMin<Finite<N>>;
62
78
 
63
79
  /**
64
80
  The actual implementation of `UnionMin`. It's private because it has some arguments that don't need to be exposed.
@@ -77,9 +93,23 @@ Note: Just supports numbers from 0 to 999.
77
93
  ```
78
94
  type A = UnionMax<1 | 3 | 2>;
79
95
  //=> 3
96
+
97
+ type B = UnionMax<number>;
98
+ //=> number
99
+
100
+ type C = UnionMax<any>;
101
+ //=> any
102
+
103
+ type D = UnionMax<never>;
104
+ //=> never
80
105
  ```
81
106
  */
82
- export type UnionMax<N extends number> = InternalUnionMax<N>;
107
+ export type UnionMax<N extends number> =
108
+ IsAnyOrNever<N> extends true ? N
109
+ : number extends N ? number
110
+ : PositiveInfinity extends N ? PositiveInfinity
111
+ : [N] extends [NegativeInfinity] ? NegativeInfinity
112
+ : InternalUnionMax<Finite<N>>;
83
113
 
84
114
  /**
85
115
  The actual implementation of `UnionMax`. It's private because it has some arguments that don't need to be exposed.
@@ -87,7 +117,7 @@ The actual implementation of `UnionMax`. It's private because it has some argume
87
117
  type InternalUnionMax<N extends number, T extends UnknownArray = []> =
88
118
  IsNever<N> extends true
89
119
  ? T['length']
90
- : T['length'] extends N
120
+ : T['length'] extends N
91
121
  ? InternalUnionMax<Exclude<N, T['length']>, T>
92
122
  : InternalUnionMax<N, [...T, unknown]>;
93
123
 
@@ -1,15 +1,16 @@
1
- import type {Simplify} from '../simplify';
2
- import type {UnknownArray} from '../unknown-array';
3
- import type {IsEqual} from '../is-equal';
4
- import type {KeysOfUnion} from '../keys-of-union';
5
- import type {RequiredKeysOf} from '../required-keys-of';
6
- import type {Merge} from '../merge';
7
- import type {IfAny} from '../if-any';
8
- import type {IfNever} from '../if-never';
9
- import type {OptionalKeysOf} from '../optional-keys-of';
10
- import type {FilterDefinedKeys, FilterOptionalKeys} from './keys';
11
- import type {NonRecursiveType} from './type';
12
- import type {ToString} from './string';
1
+ import type {Simplify} from '../simplify.d.ts';
2
+ import type {UnknownArray} from '../unknown-array.d.ts';
3
+ import type {IsEqual} from '../is-equal.d.ts';
4
+ import type {KeysOfUnion} from '../keys-of-union.d.ts';
5
+ import type {RequiredKeysOf} from '../required-keys-of.d.ts';
6
+ import type {Merge} from '../merge.d.ts';
7
+ import type {OptionalKeysOf} from '../optional-keys-of.d.ts';
8
+ import type {IsAny} from '../is-any.d.ts';
9
+ import type {If} from '../if.d.ts';
10
+ import type {IsNever} from '../is-never.d.ts';
11
+ import type {FilterDefinedKeys, FilterOptionalKeys} from './keys.d.ts';
12
+ import type {NonRecursiveType} from './type.d.ts';
13
+ import type {ToString} from './string.d.ts';
13
14
 
14
15
  /**
15
16
  Create an object type with the given key `<Key>` and value `<Value>`.
@@ -79,13 +80,13 @@ type OptionalizedUser = UndefinedToOptional<User>;
79
80
  ```
80
81
  */
81
82
  export type UndefinedToOptional<T extends object> = Simplify<
82
- {
83
+ {
83
84
  // Property is not a union with `undefined`, keep it as-is.
84
- [Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key];
85
- } & {
85
+ [Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key];
86
+ } & {
86
87
  // Property _is_ a union with defined value. Set as optional (via `?`) and remove `undefined` from the union.
87
- [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
88
- }
88
+ [Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
89
+ }
89
90
  >;
90
91
 
91
92
  /**
@@ -222,15 +223,43 @@ export type ApplyDefaultOptions<
222
223
  Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>,
223
224
  SpecifiedOptions extends Options,
224
225
  > =
225
- IfAny<SpecifiedOptions, Defaults,
226
- IfNever<SpecifiedOptions, Defaults,
227
- Simplify<Merge<Defaults, {
228
- [Key in keyof SpecifiedOptions
229
- as Key extends OptionalKeysOf<Options>
230
- ? Extract<SpecifiedOptions[Key], undefined> extends never
231
- ? Key
232
- : never
233
- : Key
234
- ]: SpecifiedOptions[Key]
235
- }> & Required<Options>> // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
236
- >>;
226
+ If<IsAny<SpecifiedOptions>, Defaults,
227
+ If<IsNever<SpecifiedOptions>, Defaults,
228
+ Simplify<Merge<Defaults, {
229
+ [Key in keyof SpecifiedOptions
230
+ as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key
231
+ ]: SpecifiedOptions[Key]
232
+ }> & Required<Options>>>>; // `& Required<Options>` ensures that `ApplyDefaultOptions<SomeOption, ...>` is always assignable to `Required<SomeOption>`
233
+
234
+ /**
235
+ Collapses literal types in a union into their corresponding primitive types, when possible. For example, `CollapseLiterals<'foo' | 'bar' | (string & {})>` returns `string`.
236
+
237
+ Note: This doesn't collapse literals within tagged types. For example, `CollapseLiterals<Tagged<'foo' | (string & {}), 'Tag'>>` returns `("foo" & Tag<"Tag", never>) | (string & Tag<"Tag", never>)` and not `string & Tag<"Tag", never>`.
238
+
239
+ Use-case: For collapsing unions created using {@link LiteralUnion}.
240
+
241
+ @example
242
+ ```
243
+ import type {LiteralUnion} from 'type-fest';
244
+
245
+ type A = CollapseLiterals<'foo' | 'bar' | (string & {})>;
246
+ //=> string
247
+
248
+ type B = CollapseLiterals<LiteralUnion<1 | 2 | 3, number>>;
249
+ //=> number
250
+
251
+ type C = CollapseLiterals<LiteralUnion<'onClick' | 'onChange', `on${string}`>>;
252
+ //=> `on${string}`
253
+
254
+ type D = CollapseLiterals<'click' | 'change' | (`on${string}` & {})>;
255
+ //=> 'click' | 'change' | `on${string}`
256
+
257
+ type E = CollapseLiterals<LiteralUnion<'foo' | 'bar', string> | null | undefined>;
258
+ //=> string | null | undefined
259
+ ```
260
+ */
261
+ export type CollapseLiterals<T> = {} extends T
262
+ ? T
263
+ : T extends infer U & {}
264
+ ? U
265
+ : T;
@@ -1,7 +1,7 @@
1
- import type {NegativeInfinity, PositiveInfinity} from '../numeric';
2
- import type {Trim} from '../trim';
3
- import type {Whitespace} from './characters';
4
- import type {BuildTuple} from './tuple';
1
+ import type {NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
2
+ import type {Trim} from '../trim.d.ts';
3
+ import type {Whitespace} from './characters.d.ts';
4
+ import type {BuildTuple} from './tuple.d.ts';
5
5
 
6
6
  /**
7
7
  Return a string representation of the given string or number.
@@ -112,16 +112,6 @@ export type StringLength<S extends string> = string extends S
112
112
  ? never
113
113
  : StringToArray<S>['length'];
114
114
 
115
- /**
116
- Returns a boolean for whether the string is lowercased.
117
- */
118
- export type IsLowerCase<T extends string> = T extends Lowercase<T> ? true : false;
119
-
120
- /**
121
- Returns a boolean for whether the string is uppercased.
122
- */
123
- export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : false;
124
-
125
115
  /**
126
116
  Returns a boolean for whether a string is whitespace.
127
117
  */
@@ -1,7 +1,7 @@
1
- import type {GreaterThan} from '../greater-than';
2
- import type {LessThan} from '../less-than';
3
- import type {NegativeInfinity, PositiveInfinity} from '../numeric';
4
- import type {UnknownArray} from '../unknown-array';
1
+ import type {GreaterThan} from '../greater-than.d.ts';
2
+ import type {LessThan} from '../less-than.d.ts';
3
+ import type {NegativeInfinity, PositiveInfinity} from '../numeric.d.ts';
4
+ import type {UnknownArray} from '../unknown-array.d.ts';
5
5
 
6
6
  /**
7
7
  Infer the length of the given tuple `<T>`.
@@ -1,5 +1,7 @@
1
- import type {IsNever} from '../is-never';
2
- import type {Primitive} from '../primitive';
1
+ import type {If} from '../if.d.ts';
2
+ import type {IsAny} from '../is-any.d.ts';
3
+ import type {IsNever} from '../is-never.d.ts';
4
+ import type {Primitive} from '../primitive.d.ts';
3
5
 
4
6
  /**
5
7
  Matches any primitive, `void`, `Date`, or `RegExp` value.
@@ -78,36 +80,51 @@ export type Not<A extends boolean> = A extends true
78
80
  : never;
79
81
 
80
82
  /**
81
- Returns a boolean for whether the given type is a union type.
83
+ An if-else-like type that resolves depending on whether the given type is `any` or `never`.
82
84
 
83
85
  @example
84
86
  ```
85
- type A = IsUnion<string | number>;
86
- //=> true
87
+ // When `T` is a NOT `any` or `never` (like `string`) => Returns `IfNotAnyOrNever` branch
88
+ type A = IfNotAnyOrNever<string, 'VALID', 'IS_ANY', 'IS_NEVER'>;
89
+ //=> 'VALID'
90
+
91
+ // When `T` is `any` => Returns `IfAny` branch
92
+ type B = IfNotAnyOrNever<any, 'VALID', 'IS_ANY', 'IS_NEVER'>;
93
+ //=> 'IS_ANY'
94
+
95
+ // When `T` is `never` => Returns `IfNever` branch
96
+ type C = IfNotAnyOrNever<never, 'VALID', 'IS_ANY', 'IS_NEVER'>;
97
+ //=> 'IS_NEVER'
98
+ ```
99
+ */
100
+ export type IfNotAnyOrNever<T, IfNotAnyOrNever, IfAny = any, IfNever = never> =
101
+ If<IsAny<T>, IfAny, If<IsNever<T>, IfNever, IfNotAnyOrNever>>;
87
102
 
88
- type B = IsUnion<string>;
103
+ /**
104
+ Returns a boolean for whether the given type is `any` or `never`.
105
+
106
+ This type can be better to use than {@link IfNotAnyOrNever `IfNotAnyOrNever`} in recursive types because it does not evaluate any branches.
107
+
108
+ @example
109
+ ```
110
+ // When `T` is a NOT `any` or `never` (like `string`) => Returns `false`
111
+ type A = IsAnyOrNever<string>;
89
112
  //=> false
113
+
114
+ // When `T` is `any` => Returns `true`
115
+ type B = IsAnyOrNever<any>;
116
+ //=> true
117
+
118
+ // When `T` is `never` => Returns `true`
119
+ type C = IsAnyOrNever<never>;
120
+ //=> true
90
121
  ```
91
122
  */
92
- export type IsUnion<T> = InternalIsUnion<T>;
123
+ export type IsAnyOrNever<T> = IsNotFalse<IsAny<T> | IsNever<T>>;
93
124
 
94
125
  /**
95
- The actual implementation of `IsUnion`.
126
+ Indicates the value of `exactOptionalPropertyTypes` compiler option.
96
127
  */
97
- type InternalIsUnion<T, U = T> =
98
- (
99
- // @link https://ghaiklor.github.io/type-challenges-solutions/en/medium-isunion.html
100
- IsNever<T> extends true
101
- ? false
102
- : T extends any
103
- ? [U] extends [T]
104
- ? false
105
- : true
106
- : never
107
- ) extends infer Result
108
- // In some cases `Result` will return `false | true` which is `boolean`,
109
- // that means `T` has at least two types and it's a union type,
110
- // so we will return `true` instead of `boolean`.
111
- ? boolean extends Result ? true
112
- : Result
113
- : never; // Should never happen
128
+ export type IsExactOptionalPropertyTypesEnabled = [(string | undefined)?] extends [string?]
129
+ ? false
130
+ : true;
@@ -1,7 +1,3 @@
1
- // Can eventually be replaced with the built-in once this library supports
2
- // TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
3
- type NoInfer<T> = T extends infer U ? U : never;
4
-
5
1
  /**
6
2
  Returns a boolean for whether the given type is `any`.
7
3
 
@@ -1,5 +1,3 @@
1
- import type {Zero} from './numeric';
2
-
3
1
  /**
4
2
  Returns a boolean for whether the given number is a float, like `1.5` or `-1.5`.
5
3
 
@@ -8,7 +6,7 @@ Use-case:
8
6
 
9
7
  @example
10
8
  ```
11
- import type {IsFloat, PositiveInfinity} from "type-fest";
9
+ import type {IsFloat, PositiveInfinity} from 'type-fest';
12
10
 
13
11
  type A = IsFloat<1.5>;
14
12
  //=> true
@@ -1,6 +1,6 @@
1
- import type {Not} from './internal';
2
- import type {IsFloat} from './is-float';
3
- import type {PositiveInfinity, NegativeInfinity} from './numeric';
1
+ import type {Not} from './internal/index.d.ts';
2
+ import type {IsFloat} from './is-float.d.ts';
3
+ import type {PositiveInfinity, NegativeInfinity} from './numeric.d.ts';
4
4
 
5
5
  /**
6
6
  Returns a boolean for whether the given number is an integer, like `-5`, `1.0`, or `100`.
@@ -10,7 +10,7 @@ Use-case:
10
10
 
11
11
  @example
12
12
  ```
13
- import type {IsInteger, PositiveInfinity} from "type-fest";
13
+ import type {IsInteger, PositiveInfinity} from 'type-fest';
14
14
 
15
15
  type A = IsInteger<1>;
16
16
  //=> true
@@ -1,8 +1,8 @@
1
- import type {Primitive} from './primitive';
2
- import type {Numeric} from './numeric';
3
- import type {IsNotFalse, IsPrimitive} from './internal';
4
- import type {IsNever} from './is-never';
5
- import type {IfNever} from './if-never';
1
+ import type {Primitive} from './primitive.d.ts';
2
+ import type {Numeric} from './numeric.d.ts';
3
+ import type {CollapseLiterals, IfNotAnyOrNever, IsNotFalse, IsPrimitive} from './internal/index.d.ts';
4
+ import type {IsNever} from './is-never.d.ts';
5
+ import type {TagContainer, UnwrapTagged} from './tagged.d.ts';
6
6
 
7
7
  /**
8
8
  Returns a boolean for whether the given type `T` is the specified `LiteralType`.
@@ -114,14 +114,18 @@ type L2 = Length<`${number}`>;
114
114
  @category Type Guard
115
115
  @category Utilities
116
116
  */
117
- export type IsStringLiteral<T> = IfNever<T, false,
117
+ export type IsStringLiteral<S> = IfNotAnyOrNever<S,
118
+ _IsStringLiteral<CollapseLiterals<S extends TagContainer<any> ? UnwrapTagged<S> : S>>,
119
+ false, false>;
120
+
121
+ export type _IsStringLiteral<S> =
118
122
  // If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
119
123
  // and since `{}` extends index signatures, the result becomes `false`.
120
- T extends string
121
- ? {} extends Record<T, never>
124
+ S extends string
125
+ ? {} extends Record<S, never>
122
126
  ? false
123
127
  : true
124
- : false>;
128
+ : false;
125
129
 
126
130
  /**
127
131
  Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
@@ -134,7 +138,7 @@ Useful for:
134
138
  ```
135
139
  import type {IsNumericLiteral} from 'type-fest';
136
140
 
137
- // https://github.com/inocan-group/inferred-types/blob/master/src/types/boolean-logic/EndsWith.ts
141
+ // https://github.com/inocan-group/inferred-types/blob/master/modules/types/src/boolean-logic/operators/EndsWith.ts
138
142
  type EndsWith<TValue, TEndsWith extends string> =
139
143
  TValue extends string
140
144
  ? IsStringLiteral<TEndsWith> extends true
@@ -264,27 +268,39 @@ Useful for:
264
268
  ```
265
269
  import type {IsLiteral} from 'type-fest';
266
270
 
267
- // https://github.com/inocan-group/inferred-types/blob/master/src/types/string-literals/StripLeading.ts
268
- export type StripLeading<A, B> =
269
- A extends string
270
- ? B extends string
271
- ? IsLiteral<A> extends true
272
- ? string extends B ? never : A extends `${B & string}${infer After}` ? After : A
273
- : string
274
- : A
275
- : A;
276
-
277
- function stripLeading<Input extends string, Strip extends string>(input: Input, strip: Strip) {
278
- return input.replace(`^${strip}`, '') as StripLeading<Input, Strip>;
279
- }
271
+ type A = IsLiteral<1>;
272
+ //=> true
280
273
 
281
- stripLeading('abc123', 'abc');
282
- //=> '123'
274
+ type B = IsLiteral<number>;
275
+ //=> false
283
276
 
284
- const str = 'abc123' as string;
277
+ type C = IsLiteral<1n>;
278
+ //=> true
285
279
 
286
- stripLeading(str, 'abc');
287
- //=> string
280
+ type D = IsLiteral<bigint>;
281
+ //=> false
282
+
283
+ type E = IsLiteral<'type-fest'>;
284
+ //=> true
285
+
286
+ type F = IsLiteral<string>;
287
+ //=> false
288
+
289
+ type G = IsLiteral<`on${string}`>;
290
+ //=> false
291
+
292
+ declare const symbolLiteral: unique symbol;
293
+ type H = IsLiteral<typeof symbolLiteral>;
294
+ //=> true
295
+
296
+ type I = IsLiteral<symbol>;
297
+ //=> false
298
+
299
+ type J = IsLiteral<true>;
300
+ //=> true
301
+
302
+ type K = IsLiteral<boolean>;
303
+ //=> false
288
304
  ```
289
305
 
290
306
  @category Type Guard
@@ -0,0 +1,36 @@
1
+ import type {AllExtend} from './all-extend.d.ts';
2
+
3
+ /**
4
+ Returns a boolean for whether the given string literal is lowercase.
5
+
6
+ @example
7
+ ```
8
+ import type {IsLowercase} from 'type-fest';
9
+
10
+ IsLowercase<'abc'>;
11
+ //=> true
12
+
13
+ IsLowercase<'Abc'>;
14
+ //=> false
15
+
16
+ IsLowercase<string>;
17
+ //=> boolean
18
+ ```
19
+ */
20
+ export type IsLowercase<S extends string> = AllExtend<_IsLowercase<S>, true>;
21
+
22
+ /**
23
+ Loops through each part in the string and returns a boolean array indicating whether each part is lowercase.
24
+ */
25
+ type _IsLowercase<S extends string, Accumulator extends boolean[] = []> = S extends `${infer First}${infer Rest}`
26
+ ? _IsLowercase<Rest, [...Accumulator, IsLowercaseHelper<First>]>
27
+ : [...Accumulator, IsLowercaseHelper<S>];
28
+
29
+ /**
30
+ Returns a boolean for whether an individual part of the string is lowercase.
31
+ */
32
+ type IsLowercaseHelper<S extends string> = S extends Lowercase<string>
33
+ ? true
34
+ : S extends Uppercase<string> | Capitalize<string> | `${string}${Uppercase<string>}${string}`
35
+ ? false
36
+ : boolean;
@@ -0,0 +1,28 @@
1
+ import type {IsAny} from './is-any.d.ts';
2
+
3
+ /**
4
+ Returns a boolean for whether the given type includes `null`.
5
+
6
+ Note: The built-in `NonNullable` type removes both `null` and `undefined`, which is not accurate for the name.
7
+
8
+ @example
9
+ ```ts
10
+ import type {IsNullable} from 'type-fest';
11
+
12
+ type A = IsNullable<string>;
13
+ //=> false
14
+
15
+ type B = IsNullable<string | null>;
16
+ //=> true
17
+
18
+ type C = IsNullable<string | undefined>;
19
+ //=> false
20
+
21
+ type D = IsNullable<string | null | undefined>;
22
+ //=> true
23
+ ```
24
+
25
+ @category Type Guard
26
+ @category Utilities
27
+ */
28
+ export type IsNullable<T> = IsAny<T> extends true ? true : Extract<T, null> extends never ? false : true;
@@ -0,0 +1,49 @@
1
+ import type {IsAny} from './is-any.d.ts';
2
+
3
+ /**
4
+ Returns a boolean for whether the given key is an optional key of type.
5
+
6
+ This is useful when writing utility types or schema validators that need to differentiate `optional` keys.
7
+
8
+ @example
9
+ ```
10
+ import type {IsOptionalKeyOf} from 'type-fest';
11
+
12
+ interface User {
13
+ name: string;
14
+ surname: string;
15
+
16
+ luckyNumber?: number;
17
+ }
18
+
19
+ interface Admin {
20
+ name: string;
21
+ surname?: string;
22
+ }
23
+
24
+ type T1 = IsOptionalKeyOf<User, 'luckyNumber'>;
25
+ //=> true
26
+
27
+ type T2 = IsOptionalKeyOf<User, 'name'>;
28
+ //=> false
29
+
30
+ type T3 = IsOptionalKeyOf<User, 'name' | 'luckyNumber'>;
31
+ //=> boolean
32
+
33
+ type T4 = IsOptionalKeyOf<User | Admin, 'name'>;
34
+ //=> false
35
+
36
+ type T5 = IsOptionalKeyOf<User | Admin, 'surname'>;
37
+ //=> boolean
38
+ ```
39
+
40
+ @category Type Guard
41
+ @category Utilities
42
+ */
43
+ export type IsOptionalKeyOf<Type extends object, Key extends keyof Type> =
44
+ IsAny<Type | Key> extends true ? never
45
+ : Key extends keyof Type
46
+ ? Type extends Record<Key, Type[Key]>
47
+ ? false
48
+ : true
49
+ : false;