type-fest 4.41.0 → 5.0.1

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
@@ -0,0 +1,42 @@
1
+ import type {IsNever} from './is-never.d.ts';
2
+ import type {IsAny} from './is-any.d.ts';
3
+
4
+ /**
5
+ A stricter, non-distributive version of `extends` for checking whether one type is assignable to another.
6
+
7
+ Unlike the built-in `extends` keyword, `ExtendsStrict`:
8
+
9
+ 1. Prevents distribution over union types by wrapping both types in tuples. For example, `ExtendsStrict<string | number, number>` returns `false`, whereas `string | number extends number` would result in `boolean`.
10
+
11
+ 2. Treats `never` as a special case: `never` doesn't extend every other type, it only extends itself (or `any`). For example, `ExtendsStrict<never, number>` returns `false` whereas `never extends number` would result in `true`.
12
+
13
+ @example
14
+ ```
15
+ import type {ExtendsStrict} from 'type-fest';
16
+
17
+ type T1 = ExtendsStrict<number | string, string>;
18
+ //=> false
19
+
20
+ type T2 = ExtendsStrict<never, number>;
21
+ //=> false
22
+
23
+ type T3 = ExtendsStrict<never, never>;
24
+ //=> true
25
+
26
+ type T4 = ExtendsStrict<string, number | string>;
27
+ //=> true
28
+
29
+ type T5 = ExtendsStrict<string, string>;
30
+ //=> true
31
+ ```
32
+
33
+ @category Improved Built-in
34
+ */
35
+ export type ExtendsStrict<Left, Right> =
36
+ IsAny<Left | Right> extends true
37
+ ? true
38
+ : IsNever<Left> extends true
39
+ ? IsNever<Right>
40
+ : [Left] extends [Right]
41
+ ? true
42
+ : false;
@@ -0,0 +1,45 @@
1
+ /**
2
+ A stricter version of {@link Extract<T, U>} that ensures every member of `U` can successfully extract something from `T`.
3
+
4
+ For example, `StrictExtract<string | number | boolean, number | bigint>` will error because `bigint` cannot extract anything from `string | number | boolean`.
5
+
6
+ @example
7
+ ```
8
+ // Valid Examples
9
+
10
+ type Example1 = ExtractStrict<{status: 'success'; data: string[]} | {status: 'error'; error: string}, {status: 'success'}>;
11
+ //=> {status: 'success'; data: string[]}
12
+
13
+ type Example2 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xs' | 's'>;
14
+ //=> 'xs' | 's'
15
+
16
+ type Example3 = ExtractStrict<{x: number; y: number} | [number, number], unknown[]>;
17
+ //=> [number, number]
18
+ ```
19
+
20
+ @example
21
+ ```
22
+ // Invalid Examples
23
+
24
+ // `'xxl'` cannot extract anything from `'xs' | 's' | 'm' | 'l' | 'xl'`
25
+ type Example1 = ExtractStrict<'xs' | 's' | 'm' | 'l' | 'xl', 'xl' | 'xxl'>;
26
+ // ~~~~~~~~~~~~
27
+ // Error: Type "'xl' | 'xxl'" does not satisfy the constraint 'never'.
28
+
29
+ // `unknown[]` cannot extract anything from `{x: number; y: number} | {x: string; y: string}`
30
+ type Example2 = ExtractStrict<{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 ExtractStrict<
38
+ T,
39
+ U extends [U] extends [
40
+ // Ensure every member of `U` extracts something from `T`
41
+ U extends unknown ? (Extract<T, U> extends never ? never : U) : never,
42
+ ]
43
+ ? unknown
44
+ : never,
45
+ > = Extract<T, U>;
@@ -60,5 +60,5 @@ type FindBar = FindGlobalInstanceType<'Bar'>; // Works
60
60
  */
61
61
  export type FindGlobalInstanceType<Name extends string> =
62
62
  Name extends string
63
- ? typeof globalThis extends Record<Name, abstract new (...arguments: any[]) => infer T> ? T : never
63
+ ? typeof globalThis extends Record<Name, abstract new (...arguments_: any[]) => infer T> ? T : never
64
64
  : never;
@@ -34,8 +34,8 @@ guestFencingTeam.push('Sam');
34
34
  @see ReadonlyTuple
35
35
  */
36
36
  export type FixedLengthArray<Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick<
37
- ArrayPrototype,
38
- Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys>
37
+ ArrayPrototype,
38
+ Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys>
39
39
  > & {
40
40
  [index: number]: Element;
41
41
  [Symbol.iterator]: () => IterableIterator<Element>;
package/source/get.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type {ApplyDefaultOptions, StringDigit, ToString} from './internal';
2
- import type {LiteralStringUnion} from './literal-union';
3
- import type {Paths} from './paths';
4
- import type {Split} from './split';
5
- import type {StringKeyOf} from './string-key-of';
1
+ import type {ApplyDefaultOptions, ToString} from './internal/index.d.ts';
2
+ import type {LiteralStringUnion} from './literal-union.d.ts';
3
+ import type {Paths} from './paths.d.ts';
4
+ import type {Split} from './split.d.ts';
5
+ import type {KeyAsString} from './key-as-string.d.ts';
6
+ import type {DigitCharacter} from './characters.d.ts';
6
7
 
7
8
  type GetOptions = {
8
9
  /**
@@ -27,9 +28,9 @@ type GetWithPath<BaseType, Keys, Options extends Required<GetOptions>> =
27
28
  ? BaseType
28
29
  : Keys extends readonly [infer Head, ...infer Tail]
29
30
  ? GetWithPath<
30
- PropertyOf<BaseType, Extract<Head, string>, Options>,
31
- Extract<Tail, string[]>,
32
- Options
31
+ PropertyOf<BaseType, Extract<Head, string>, Options>,
32
+ Extract<Tail, string[]>,
33
+ Options
33
34
  >
34
35
  : never;
35
36
 
@@ -64,7 +65,7 @@ ToPath<'foo[0].bar.baz'>
64
65
  //=> ['foo', '0', 'bar', 'baz']
65
66
  ```
66
67
  */
67
- type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.'>;
68
+ type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.', {strictLiteralChecks: false}>;
68
69
 
69
70
  /**
70
71
  Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`.
@@ -111,7 +112,7 @@ type WithStringsKeys = keyof WithStrings;
111
112
  ```
112
113
  */
113
114
  type WithStringKeys<BaseType> = {
114
- [Key in StringKeyOf<BaseType>]: UncheckedIndex<BaseType, Key>
115
+ [Key in KeyAsString<BaseType>]: UncheckedIndex<BaseType, Key>
115
116
  };
116
117
 
117
118
  /**
@@ -150,7 +151,7 @@ type PropertyOf<BaseType, Key extends string, Options extends Required<GetOption
150
151
  length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
151
152
  }
152
153
  ? (
153
- ConsistsOnlyOf<Key, StringDigit> extends true
154
+ ConsistsOnlyOf<Key, DigitCharacter> extends true
154
155
  ? Strictify<Item, Options>
155
156
  : unknown
156
157
  )
@@ -213,7 +214,7 @@ export type Get<
213
214
  Options extends GetOptions = {},
214
215
  > =
215
216
  GetWithPath<
216
- BaseType,
217
- Path extends string ? ToPath<Path> : Path,
218
- ApplyDefaultOptions<GetOptions, DefaultGetOptions, Options>
217
+ BaseType,
218
+ Path extends string ? ToPath<Path> : Path,
219
+ ApplyDefaultOptions<GetOptions, DefaultGetOptions, Options>
219
220
  >;
@@ -0,0 +1 @@
1
+ export type * from './observable-like.d.ts';
@@ -9,6 +9,7 @@ declare global {
9
9
  @remarks
10
10
  The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021.
11
11
  As well, some guidance on making an `Observable` to not include `closed` property.
12
+
12
13
  @see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
13
14
  @see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
14
15
  @see https://github.com/benlesh/symbol-observable#making-an-object-observable
@@ -23,10 +24,12 @@ export type Unsubscribable = {
23
24
  @category Observable
24
25
  */
25
26
  type OnNext<ValueType> = (value: ValueType) => void;
27
+
26
28
  /**
27
29
  @category Observable
28
30
  */
29
31
  type OnError = (error: unknown) => void;
32
+
30
33
  /**
31
34
  @category Observable
32
35
  */
@@ -44,6 +47,13 @@ export type Observer<ValueType> = {
44
47
  /**
45
48
  Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable).
46
49
 
50
+ You must import it as a sub-import:
51
+
52
+ @example
53
+ ```
54
+ import type {ObservableLike} from 'type-fest/globals';
55
+ ```
56
+
47
57
  @remarks
48
58
  The TC39 Observable proposal defines 2 forms of `subscribe()`:
49
59
  1. Three callback arguments: `subscribe(observer: OnNext<ValueType>, onError?: OnError, onComplete?: OnComplete): Unsubscribable;`
@@ -1,4 +1,4 @@
1
- import type {GreaterThan} from './greater-than';
1
+ import type {GreaterThan} from './greater-than.d.ts';
2
2
 
3
3
  /**
4
4
  Returns a boolean for whether a given number is greater than or equal to another number.
@@ -1,8 +1,8 @@
1
- import type {NumberAbsolute, PositiveNumericStringGt} from './internal';
2
- import type {IsEqual} from './is-equal';
3
- import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric';
4
- import type {And} from './and';
5
- import type {Or} from './or';
1
+ import type {NumberAbsolute, PositiveNumericStringGt} from './internal/index.d.ts';
2
+ import type {IsEqual} from './is-equal.d.ts';
3
+ import type {PositiveInfinity, NegativeInfinity, IsNegative} from './numeric.d.ts';
4
+ import type {And} from './and.d.ts';
5
+ import type {Or} from './or.d.ts';
6
6
 
7
7
  /**
8
8
  Returns a boolean for whether a given number is greater than another number.
@@ -31,13 +31,13 @@ export type GreaterThan<A extends number, B extends number> =
31
31
  IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
32
32
  ] extends infer R extends [boolean, boolean, boolean, boolean]
33
33
  ? Or<
34
- And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
35
- And<IsEqual<R[3], true>, IsEqual<R[1], false>>
34
+ And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
35
+ And<IsEqual<R[3], true>, IsEqual<R[1], false>>
36
36
  > extends true
37
37
  ? true
38
38
  : Or<
39
- And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
40
- And<IsEqual<R[2], true>, IsEqual<R[0], false>>
39
+ And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
40
+ And<IsEqual<R[2], true>, IsEqual<R[0], false>>
41
41
  > extends true
42
42
  ? false
43
43
  : true extends R[number]
@@ -1,4 +1,4 @@
1
- import type {OptionalKeysOf} from './optional-keys-of';
1
+ import type {OptionalKeysOf} from './optional-keys-of.d.ts';
2
2
 
3
3
  /**
4
4
  Creates a type that represents `true` or `false` depending on whether the given type has any optional fields.
@@ -1,4 +1,4 @@
1
- import type {ReadonlyKeysOf} from './readonly-keys-of';
1
+ import type {ReadonlyKeysOf} from './readonly-keys-of.d.ts';
2
2
 
3
3
  /**
4
4
  Creates a type that represents `true` or `false` depending on whether the given type has any readonly fields.
@@ -1,4 +1,4 @@
1
- import type {RequiredKeysOf} from './required-keys-of';
1
+ import type {RequiredKeysOf} from './required-keys-of.d.ts';
2
2
 
3
3
  /**
4
4
  Creates a type that represents `true` or `false` depending on whether the given type has any required fields.
@@ -1,4 +1,4 @@
1
- import type {WritableKeysOf} from './writable-keys-of';
1
+ import type {WritableKeysOf} from './writable-keys-of.d.ts';
2
2
 
3
3
  /**
4
4
  Creates a type that represents `true` or `false` depending on whether the given type has any writable fields.
@@ -1,8 +1,10 @@
1
- import type {IsAny} from './is-any';
1
+ import type {IsAny} from './is-any.d.ts';
2
2
 
3
3
  /**
4
4
  An if-else-like type that resolves depending on whether the given type is `any`.
5
5
 
6
+ @deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7
+
6
8
  @see {@link IsAny}
7
9
 
8
10
  @example
@@ -1,8 +1,10 @@
1
- import type {IsEmptyObject} from './empty-object';
1
+ import type {IsEmptyObject} from './empty-object.d.ts';
2
2
 
3
3
  /**
4
4
  An if-else-like type that resolves depending on whether the given type is `{}`.
5
5
 
6
+ @deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7
+
6
8
  @see {@link IsEmptyObject}
7
9
 
8
10
  @example
@@ -1,8 +1,10 @@
1
- import type {IsNever} from './is-never';
1
+ import type {IsNever} from './is-never.d.ts';
2
2
 
3
3
  /**
4
4
  An if-else-like type that resolves depending on whether the given type is `never`.
5
5
 
6
+ @deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7
+
6
8
  @see {@link IsNever}
7
9
 
8
10
  @example
@@ -1,8 +1,10 @@
1
- import type {IsNull} from './is-null';
1
+ import type {IsNull} from './is-null.d.ts';
2
2
 
3
3
  /**
4
4
  An if-else-like type that resolves depending on whether the given type is `null`.
5
5
 
6
+ @deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7
+
6
8
  @see {@link IsNull}
7
9
 
8
10
  @example
@@ -1,8 +1,10 @@
1
- import type {IsUnknown} from './is-unknown';
1
+ import type {IsUnknown} from './is-unknown.d.ts';
2
2
 
3
3
  /**
4
4
  An if-else-like type that resolves depending on whether the given type is `unknown`.
5
5
 
6
+ @deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7
+
6
8
  @see {@link IsUnknown}
7
9
 
8
10
  @example
package/source/if.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import type {IsNever} from './is-never.d.ts';
2
+
3
+ /**
4
+ An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
5
+
6
+ Use-cases:
7
+ - You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`.
8
+
9
+ Note:
10
+ - Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`.
11
+ - Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`.
12
+
13
+ @example
14
+ ```
15
+ import {If} from 'type-fest';
16
+
17
+ type A = If<true, 'yes', 'no'>;
18
+ //=> 'yes'
19
+
20
+ type B = If<false, 'yes', 'no'>;
21
+ //=> 'no'
22
+
23
+ type C = If<boolean, 'yes', 'no'>;
24
+ //=> 'yes' | 'no'
25
+
26
+ type D = If<any, 'yes', 'no'>;
27
+ //=> 'yes' | 'no'
28
+
29
+ type E = If<never, 'yes', 'no'>;
30
+ //=> 'no'
31
+ ```
32
+
33
+ @example
34
+ ```
35
+ import {If, IsAny, IsNever} from 'type-fest';
36
+
37
+ type A = If<IsAny<unknown>, 'is any', 'not any'>;
38
+ //=> 'not any'
39
+
40
+ type B = If<IsNever<never>, 'is never', 'not never'>;
41
+ //=> 'is never'
42
+ ```
43
+
44
+ @example
45
+ ```
46
+ import {If, IsEqual} from 'type-fest';
47
+
48
+ type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
49
+
50
+ type A = IfEqual<string, string, 'equal', 'not equal'>;
51
+ //=> 'equal'
52
+
53
+ type B = IfEqual<string, number, 'equal', 'not equal'>;
54
+ //=> 'not equal'
55
+ ```
56
+
57
+ @category Type Guard
58
+ @category Utilities
59
+ */
60
+ export type If<Type extends boolean, IfBranch, ElseBranch> =
61
+ IsNever<Type> extends true
62
+ ? ElseBranch
63
+ : Type extends true
64
+ ? IfBranch
65
+ : ElseBranch;
@@ -1,4 +1,4 @@
1
- import type {IsEqual} from './is-equal';
1
+ import type {IsEqual} from './is-equal.d.ts';
2
2
 
3
3
  /**
4
4
  Returns a boolean for whether the given array includes the given item.
@@ -1,5 +1,5 @@
1
- import type {IntRange} from './int-range';
2
- import type {Sum} from './sum';
1
+ import type {IntRange} from './int-range.d.ts';
2
+ import type {Sum} from './sum.d.ts';
3
3
 
4
4
  /**
5
5
  Generate a union of numbers.
@@ -1,5 +1,5 @@
1
- import type {BuildTuple} from './internal';
2
- import type {Subtract} from './subtract';
1
+ import type {BuildTuple} from './internal/index.d.ts';
2
+ import type {Subtract} from './subtract.d.ts';
3
3
 
4
4
  /**
5
5
  Generate a union of numbers.
@@ -41,8 +41,10 @@ type PrivateIntRange<
41
41
  Start extends number,
42
42
  End extends number,
43
43
  Step extends number,
44
- Gap extends number = Subtract<Step, 1>, // The gap between each number, gap = step - 1
45
- List extends unknown[] = BuildTuple<Start, never>, // The final `List` is `[...StartLengthTuple, ...[number, ...GapLengthTuple], ...[number, ...GapLengthTuple], ... ...]`, so can initialize the `List` with `[...StartLengthTuple]`
44
+ // The gap between each number, gap = step - 1
45
+ Gap extends number = Subtract<Step, 1>,
46
+ // The final `List` is `[...StartLengthTuple, ...[number, ...GapLengthTuple], ...[number, ...GapLengthTuple], ... ...]`, so can initialize the `List` with `[...StartLengthTuple]`
47
+ List extends unknown[] = BuildTuple<Start, never>,
46
48
  EndLengthTuple extends unknown[] = BuildTuple<End>,
47
49
  > = Gap extends 0 ?
48
50
  // Handle the case that without `Step`
@@ -1,5 +1,8 @@
1
- import type {IfNever} from '../if-never';
2
- import type {UnknownArray} from '../unknown-array';
1
+ import type {If} from '../if.d.ts';
2
+ import type {IsNever} from '../is-never.d.ts';
3
+ import type {OptionalKeysOf} from '../optional-keys-of.d.ts';
4
+ import type {UnknownArray} from '../unknown-array.d.ts';
5
+ import type {IsExactOptionalPropertyTypesEnabled, IfNotAnyOrNever} from './type.d.ts';
3
6
 
4
7
  /**
5
8
  Infer the length of the given array `<T>`.
@@ -91,36 +94,65 @@ T extends readonly [...infer U] ?
91
94
  /**
92
95
  Returns whether the given array `T` is readonly.
93
96
  */
94
- export type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
97
+ export type IsArrayReadonly<T extends UnknownArray> = If<IsNever<T>, false, T extends unknown[] ? false : true>;
95
98
 
96
99
  /**
97
- An if-else-like type that resolves depending on whether the given array is readonly.
98
-
99
- @see {@link IsArrayReadonly}
100
+ Transforms a tuple type by replacing it's rest element with a single element that has the same type as the rest element, while keeping all the non-rest elements intact.
100
101
 
101
102
  @example
102
103
  ```
103
- import type {ArrayTail} from 'type-fest';
104
+ type A = CollapseRestElement<[string, string, ...number[]]>;
105
+ //=> [string, string, number]
106
+
107
+ type B = CollapseRestElement<[...string[], number, number]>;
108
+ //=> [string, number, number]
104
109
 
105
- type ReadonlyPreservingArrayTail<TArray extends readonly unknown[]> =
106
- ArrayTail<TArray> extends infer Tail
107
- ? IfArrayReadonly<TArray, Readonly<Tail>, Tail>
108
- : never;
110
+ type C = CollapseRestElement<[string, string, ...Array<number | bigint>]>;
111
+ //=> [string, string, number | bigint]
109
112
 
110
- type ReadonlyTail = ReadonlyPreservingArrayTail<readonly [string, number, boolean]>;
111
- //=> readonly [number, boolean]
113
+ type D = CollapseRestElement<[string, number]>;
114
+ //=> [string, number]
115
+ ```
112
116
 
113
- type NonReadonlyTail = ReadonlyPreservingArrayTail<[string, number, boolean]>;
114
- //=> [number, boolean]
117
+ Note: Optional modifiers (`?`) are removed from elements unless the `exactOptionalPropertyTypes` compiler option is disabled. When disabled, there's an additional `| undefined` for optional elements.
115
118
 
116
- type ShouldBeTrue = IfArrayReadonly<readonly unknown[]>;
117
- //=> true
119
+ @example
120
+ ```
121
+ // `exactOptionalPropertyTypes` enabled
122
+ type A = CollapseRestElement<[string?, string?, ...number[]]>;
123
+ //=> [string, string, number]
118
124
 
119
- type ShouldBeBar = IfArrayReadonly<unknown[], 'foo', 'bar'>;
120
- //=> 'bar'
125
+ // `exactOptionalPropertyTypes` disabled
126
+ type B = CollapseRestElement<[string?, string?, ...number[]]>;
127
+ //=> [string | undefined, string | undefined, number]
121
128
  ```
122
129
  */
123
- export type IfArrayReadonly<T extends UnknownArray, TypeIfArrayReadonly = true, TypeIfNotArrayReadonly = false> =
124
- IsArrayReadonly<T> extends infer Result
125
- ? Result extends true ? TypeIfArrayReadonly : TypeIfNotArrayReadonly
130
+ export type CollapseRestElement<TArray extends UnknownArray> = IfNotAnyOrNever<TArray, _CollapseRestElement<TArray>>;
131
+
132
+ type _CollapseRestElement<
133
+ TArray extends UnknownArray,
134
+ ForwardAccumulator extends UnknownArray = [],
135
+ BackwardAccumulator extends UnknownArray = [],
136
+ > =
137
+ TArray extends UnknownArray // For distributing `TArray`
138
+ ? keyof TArray & `${number}` extends never
139
+ // Enters this branch, if `TArray` is empty (e.g., []),
140
+ // or `TArray` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`).
141
+ ? TArray extends readonly [...infer Rest, infer Last]
142
+ ? _CollapseRestElement<Rest, ForwardAccumulator, [Last, ...BackwardAccumulator]> // Accumulate elements that are present after the rest element.
143
+ : TArray extends readonly []
144
+ ? [...ForwardAccumulator, ...BackwardAccumulator]
145
+ : [...ForwardAccumulator, TArray[number], ...BackwardAccumulator] // Add the rest element between the accumulated elements.
146
+ : TArray extends readonly [(infer First)?, ...infer Rest]
147
+ ? _CollapseRestElement<
148
+ Rest,
149
+ [
150
+ ...ForwardAccumulator,
151
+ '0' extends OptionalKeysOf<TArray>
152
+ ? If<IsExactOptionalPropertyTypesEnabled, First, First | undefined> // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
153
+ : First,
154
+ ],
155
+ BackwardAccumulator
156
+ >
157
+ : never // Should never happen, since `[(infer First)?, ...infer Rest]` is a top-type for arrays.
126
158
  : never; // Should never happen
@@ -1,7 +1,3 @@
1
- export type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
2
-
3
- export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
4
-
5
1
  export type Whitespace =
6
2
  | '\u{9}' // '\t'
7
3
  | '\u{A}' // '\n'
@@ -1,8 +1,8 @@
1
- export type * from './array';
2
- export type * from './characters';
3
- export type * from './keys';
4
- export type * from './numeric';
5
- export type * from './object';
6
- export type * from './string';
7
- export type * from './tuple';
8
- export type * from './type';
1
+ export type * from './array.d.ts';
2
+ export type * from './characters.d.ts';
3
+ export type * from './keys.d.ts';
4
+ export type * from './numeric.d.ts';
5
+ export type * from './object.d.ts';
6
+ export type * from './string.d.ts';
7
+ export type * from './tuple.d.ts';
8
+ export type * from './type.d.ts';
@@ -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
  ```