@depup/type-fest 5.5.0-depup.0 → 5.10.0-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +2 -2
  2. package/changes.json +1 -1
  3. package/index.d.ts +17 -8
  4. package/package.json +9 -6
  5. package/readme.md +75 -61
  6. package/source/absolute.d.ts +52 -0
  7. package/source/all-extend.d.ts +9 -5
  8. package/source/all-union-fields.d.ts +18 -18
  9. package/source/and.d.ts +1 -1
  10. package/source/array-reverse.d.ts +17 -15
  11. package/source/array-splice.d.ts +24 -24
  12. package/source/array-tail.d.ts +7 -7
  13. package/source/camel-case.d.ts +38 -5
  14. package/source/camel-cased-properties-deep.d.ts +11 -4
  15. package/source/camel-cased-properties.d.ts +5 -1
  16. package/source/conditional-keys.d.ts +1 -1
  17. package/source/delimiter-case.d.ts +11 -9
  18. package/source/delimiter-cased-properties-deep.d.ts +8 -1
  19. package/source/delimiter-cased-properties.d.ts +5 -1
  20. package/source/empty-object.d.ts +1 -1
  21. package/source/entries.d.ts +1 -1
  22. package/source/entry.d.ts +1 -1
  23. package/source/exclude-exactly.d.ts +11 -11
  24. package/source/exclude-rest-element.d.ts +4 -4
  25. package/source/exclusify-union.d.ts +4 -4
  26. package/source/extends-strict.d.ts +129 -22
  27. package/source/extract-exactly.d.ts +56 -0
  28. package/source/get.d.ts +1 -1
  29. package/source/greater-than.d.ts +3 -2
  30. package/source/has-optional-keys.d.ts +1 -1
  31. package/source/has-readonly-keys.d.ts +1 -1
  32. package/source/has-required-keys.d.ts +1 -1
  33. package/source/has-writable-keys.d.ts +1 -1
  34. package/source/int-closed-range.d.ts +5 -4
  35. package/source/int-range.d.ts +57 -12
  36. package/source/internal/array.d.ts +22 -21
  37. package/source/internal/keys.d.ts +9 -9
  38. package/source/internal/numeric.d.ts +19 -65
  39. package/source/internal/object.d.ts +44 -6
  40. package/source/internal/string.d.ts +1 -76
  41. package/source/internal/tuple.d.ts +2 -2
  42. package/source/internal/type.d.ts +16 -10
  43. package/source/is-boolean-literal.d.ts +39 -0
  44. package/source/is-integer.d.ts +8 -8
  45. package/source/is-literal.d.ts +43 -267
  46. package/source/is-numeric-literal.d.ts +50 -0
  47. package/source/is-string-literal.d.ts +72 -0
  48. package/source/is-symbol-literal.d.ts +39 -0
  49. package/source/is-tuple.d.ts +3 -3
  50. package/source/is-union.d.ts +12 -12
  51. package/source/iterable-element.d.ts +5 -5
  52. package/source/jsonify.d.ts +5 -9
  53. package/source/kebab-case.d.ts +1 -0
  54. package/source/kebab-cased-properties-deep.d.ts +7 -0
  55. package/source/kebab-cased-properties.d.ts +5 -1
  56. package/source/keys-of-union.d.ts +2 -2
  57. package/source/last-array-element.d.ts +66 -13
  58. package/source/less-than-or-equal.d.ts +1 -1
  59. package/source/literal-to-primitive.d.ts +1 -1
  60. package/source/literal-union.d.ts +1 -1
  61. package/source/merge-deep.d.ts +3 -3
  62. package/source/merge-exclusive.d.ts +3 -3
  63. package/source/multidimensional-array.d.ts +1 -1
  64. package/source/multidimensional-readonly-array.d.ts +1 -1
  65. package/source/non-nullable-deep.d.ts +102 -0
  66. package/source/numeric.d.ts +3 -3
  67. package/source/object-merge.d.ts +21 -16
  68. package/source/omit-deep.d.ts +22 -22
  69. package/source/or.d.ts +1 -1
  70. package/source/package-json.d.ts +7 -7
  71. package/source/partial-deep.d.ts +3 -1
  72. package/source/pascal-case.d.ts +1 -0
  73. package/source/pascal-cased-properties-deep.d.ts +7 -0
  74. package/source/pascal-cased-properties.d.ts +5 -1
  75. package/source/pick-deep.d.ts +2 -0
  76. package/source/readonly-deep.d.ts +5 -3
  77. package/source/remove-prefix.d.ts +16 -34
  78. package/source/remove-suffix.d.ts +114 -0
  79. package/source/rename-keys.d.ts +163 -0
  80. package/source/replace.d.ts +2 -2
  81. package/source/require-all-or-none.d.ts +5 -5
  82. package/source/require-at-least-one.d.ts +9 -11
  83. package/source/require-exactly-one.d.ts +7 -7
  84. package/source/require-one-or-none.d.ts +5 -5
  85. package/source/required-deep.d.ts +3 -1
  86. package/source/schema.d.ts +16 -8
  87. package/source/screaming-snake-case.d.ts +1 -0
  88. package/source/set-non-nullable-deep.d.ts +8 -4
  89. package/source/set-non-nullable.d.ts +1 -1
  90. package/source/set-optional.d.ts +5 -5
  91. package/source/set-readonly.d.ts +3 -3
  92. package/source/set-required-deep.d.ts +3 -2
  93. package/source/set-required.d.ts +13 -12
  94. package/source/shared-union-fields-deep.d.ts +6 -4
  95. package/source/shared-union-fields.d.ts +9 -9
  96. package/source/snake-case.d.ts +1 -0
  97. package/source/snake-cased-properties-deep.d.ts +7 -0
  98. package/source/snake-cased-properties.d.ts +5 -1
  99. package/source/some-extend.d.ts +9 -5
  100. package/source/split-on-rest-element.d.ts +20 -17
  101. package/source/split.d.ts +22 -11
  102. package/source/string-length.d.ts +38 -0
  103. package/source/string-repeat.d.ts +48 -21
  104. package/source/string-slice.d.ts +1 -1
  105. package/source/string-to-array.d.ts +97 -0
  106. package/source/string-to-number.d.ts +67 -0
  107. package/source/subtract.d.ts +4 -3
  108. package/source/sum.d.ts +5 -4
  109. package/source/tagged.d.ts +3 -5
  110. package/source/tsconfig-json.d.ts +40 -8
  111. package/source/tuple-of.d.ts +42 -8
  112. package/source/typed-array.d.ts +6 -0
  113. package/source/union-length.d.ts +27 -0
  114. package/source/union-max.d.ts +56 -0
  115. package/source/union-to-intersection.d.ts +1 -1
  116. package/source/union-to-tuple.d.ts +8 -4
  117. package/source/unwrap-required.d.ts +37 -0
  118. package/source/words.d.ts +30 -4
  119. package/source/writable.d.ts +14 -14
  120. package/source/xor.d.ts +1 -1
@@ -0,0 +1,50 @@
1
+ import type {CollapseLiterals, UnwrapBrand} from './internal/object.d.ts';
2
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
3
+
4
+ /**
5
+ 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).
6
+
7
+ @example
8
+ ```
9
+ import type {IsNumericLiteral} from 'type-fest';
10
+
11
+ type A = IsNumericLiteral<0>;
12
+ //=> true
13
+
14
+ type B = IsNumericLiteral<number>;
15
+ //=> false
16
+
17
+ type C = IsNumericLiteral<100n>;
18
+ //=> true
19
+
20
+ type D = IsNumericLiteral<bigint>;
21
+ //=> false
22
+
23
+ type E = IsNumericLiteral<1 | 2 | 10n | 20n>;
24
+ //=> true
25
+
26
+ type F = IsNumericLiteral<number | bigint>;
27
+ //=> false
28
+
29
+ type G = IsNumericLiteral<1 | bigint>;
30
+ //=> boolean
31
+ ```
32
+
33
+ @category Type Guard
34
+ @category Utilities
35
+ */
36
+ export type IsNumericLiteral<T> = IfNotAnyOrNever<T, {
37
+ ifNot: _IsNumericLiteral<CollapseLiterals<UnwrapBrand<T>>>;
38
+ ifAny: false;
39
+ ifNever: false;
40
+ }>;
41
+
42
+ type _IsNumericLiteral<T> = T extends number | bigint
43
+ ? number extends T
44
+ ? false
45
+ : bigint extends T
46
+ ? false
47
+ : true
48
+ : false;
49
+
50
+ export {};
@@ -0,0 +1,72 @@
1
+ import type {CollapseLiterals, UnwrapBrand} from './internal/object.d.ts';
2
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
3
+
4
+ /**
5
+ Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
6
+
7
+ The implementation of this type is inspired by the trick mentioned in this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747).
8
+
9
+ @example
10
+ ```
11
+ import type {IsStringLiteral} from 'type-fest';
12
+
13
+ type A = IsStringLiteral<'foo'>;
14
+ //=> true
15
+
16
+ type B = IsStringLiteral<string>;
17
+ //=> false
18
+
19
+ // String types with infinite set of possible values return `false`
20
+ type C = IsStringLiteral<`on${string}`>;
21
+ //=> false
22
+
23
+ type D = IsStringLiteral<Uppercase<string>>;
24
+ //=> false
25
+
26
+ type E = IsStringLiteral<'foo' | 'bar' | 'baz'>;
27
+ //=> true
28
+
29
+ type F = IsStringLiteral<'sm' | 'md' | 'lg' | `${number}px`>;
30
+ //=> boolean
31
+ ```
32
+
33
+ @example
34
+ ```
35
+ import type {IsStringLiteral} from 'type-fest';
36
+
37
+ type StringLength<S extends string, Counter extends never[] = []> =
38
+ IsStringLiteral<S> extends true
39
+ ? S extends `${string}${infer Tail}`
40
+ ? StringLength<Tail, [...Counter, never]>
41
+ : Counter['length']
42
+ : number; // return `number` for non-literal string types
43
+
44
+ type L1 = StringLength<'foobar'>;
45
+ //=> 6
46
+
47
+ type L2 = StringLength<Lowercase<string>>;
48
+ //=> number
49
+
50
+ type L3 = StringLength<`${number}`>;
51
+ //=> number
52
+ ```
53
+
54
+ @category Type Guard
55
+ @category Utilities
56
+ */
57
+ export type IsStringLiteral<S> = IfNotAnyOrNever<S, {
58
+ ifNot: _IsStringLiteral<CollapseLiterals<UnwrapBrand<S>>>;
59
+ ifAny: false;
60
+ ifNever: false;
61
+ }>;
62
+
63
+ type _IsStringLiteral<S> =
64
+ // If `S` is an infinite string type (e.g., `on${string}`), `Record<S, never>` produces an index signature,
65
+ // and since `{}` extends index signatures, the result becomes `false`.
66
+ S extends string
67
+ ? {} extends Record<S, never>
68
+ ? false
69
+ : true
70
+ : false;
71
+
72
+ export {};
@@ -0,0 +1,39 @@
1
+ import type {CollapseLiterals, UnwrapBrand} from './internal/object.d.ts';
2
+ import type {IfNotAnyOrNever} from './internal/type.d.ts';
3
+
4
+ /**
5
+ Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
6
+
7
+ @example
8
+ ```
9
+ import type {IsSymbolLiteral} from 'type-fest';
10
+
11
+ declare const symbolLiteral1: unique symbol;
12
+ declare const symbolLiteral2: unique symbol;
13
+
14
+ type A = IsSymbolLiteral<typeof symbolLiteral1>;
15
+ //=> true
16
+
17
+ type B = IsSymbolLiteral<symbol>;
18
+ //=> false
19
+
20
+ type C = IsSymbolLiteral<typeof symbolLiteral1 | typeof symbolLiteral2>;
21
+ //=> true
22
+ ```
23
+
24
+ @category Type Guard
25
+ @category Utilities
26
+ */
27
+ export type IsSymbolLiteral<T> = IfNotAnyOrNever<T, {
28
+ ifNot: _IsSymbolLiteral<CollapseLiterals<UnwrapBrand<T>>>;
29
+ ifAny: false;
30
+ ifNever: false;
31
+ }>;
32
+
33
+ type _IsSymbolLiteral<T> = T extends symbol
34
+ ? symbol extends T
35
+ ? false
36
+ : true
37
+ : false;
38
+
39
+ export {};
@@ -81,9 +81,9 @@ type _IsTuple<
81
81
  TArray extends unknown // For distributing `TArray`
82
82
  ? number extends TArray['length']
83
83
  ? Options['fixedLengthOnly'] extends false
84
- ? If<IsNever<keyof TArray & `${number}`>,
85
- TArray extends readonly [...any, any] ? true : false, // To handle cases where a non-rest element follows a rest element, e.g., `[...number[], number]`
86
- true>
84
+ ? '0' extends keyof TArray
85
+ ? true
86
+ : TArray extends readonly [...any, any] ? true : false // To handle cases where a non-rest element follows a rest element, e.g., `[...number[], number]`
87
87
  : false
88
88
  : true
89
89
  : false
@@ -21,20 +21,20 @@ export type IsUnion<T> = InternalIsUnion<T>;
21
21
  The actual implementation of `IsUnion`.
22
22
  */
23
23
  type InternalIsUnion<T, U = T> =
24
- (
25
- IsNever<T> extends true
26
- ? false
27
- : T extends any
28
- ? IsEqual<U, T> extends true
29
- ? false
30
- : true
31
- : never
32
- ) extends infer Result
24
+ (
25
+ IsNever<T> extends true
26
+ ? false
27
+ : T extends any
28
+ ? IsEqual<U, T> extends true
29
+ ? false
30
+ : true
31
+ : never
32
+ ) extends infer Result
33
33
  // In some cases `Result` will return `false | true` which is `boolean`,
34
34
  // that means `T` has at least two types and it's a union type,
35
35
  // so we will return `true` instead of `boolean`.
36
- ? boolean extends Result ? true
37
- : Result
38
- : never; // Should never happen
36
+ ? boolean extends Result ? true
37
+ : Result
38
+ : never; // Should never happen
39
39
 
40
40
  export {};
@@ -57,10 +57,10 @@ type Fruit = IterableElement<typeof fruits>;
57
57
  @category Iterable
58
58
  */
59
59
  export type IterableElement<TargetIterable> =
60
- TargetIterable extends Iterable<infer ElementType> ?
61
- ElementType :
62
- TargetIterable extends AsyncIterable<infer ElementType> ?
63
- ElementType :
64
- never;
60
+ TargetIterable extends Iterable<infer ElementType>
61
+ ? ElementType
62
+ : TargetIterable extends AsyncIterable<infer ElementType>
63
+ ? ElementType
64
+ : never;
65
65
 
66
66
  export {};
@@ -25,15 +25,11 @@ type JsonifyList<T extends UnknownArray> = T extends readonly []
25
25
  ? JsonValue[]
26
26
  : Array<T[number] extends NotJsonable ? null : Jsonify<UndefinedToNull<T[number]>>>;
27
27
 
28
- type FilterJsonableKeys<T extends object> = {
29
- [Key in keyof T]: T[Key] extends NotJsonable ? never : Key;
30
- }[keyof T];
31
-
32
28
  /**
33
29
  JSON serialize objects (not including arrays) and classes.
34
30
  */
35
31
  type JsonifyObject<T extends object> = {
36
- [Key in keyof Pick<T, FilterJsonableKeys<T>>]: Jsonify<T[Key]>;
32
+ [Key in keyof T as T[Key] extends NotJsonable ? never : Key]: Jsonify<T[Key]>;
37
33
  };
38
34
 
39
35
  /**
@@ -98,13 +94,13 @@ export type Jsonify<T> = IsAny<T> extends true
98
94
  ? null
99
95
  : T extends JsonPrimitive
100
96
  ? T
101
- : // Any object with toJSON is special case
102
- T extends {toJSON(): infer J}
97
+ // Any object with toJSON is special case
98
+ : T extends {toJSON(): infer J}
103
99
  ? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
104
100
  ? J // Then T is Jsonable and its Jsonable value is J
105
101
  : Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
106
- : // Instanced primitives are objects
107
- T extends Number
102
+ // Instanced primitives are objects
103
+ : T extends Number
108
104
  ? number
109
105
  : T extends String
110
106
  ? string
@@ -15,6 +15,7 @@ import type {KebabCase} from 'type-fest';
15
15
 
16
16
  const someVariable: KebabCase<'fooBar'> = 'foo-bar';
17
17
  const someVariableNoSplitOnNumbers: KebabCase<'p2pNetwork', {splitOnNumbers: false}> = 'p2p-network';
18
+ const someVariableWithPunctuation: KebabCase<'div.card::after', {splitOnPunctuation: true}> = 'div-card-after';
18
19
 
19
20
  // Advanced
20
21
 
@@ -51,6 +51,13 @@ const splitOnNumbers: KebabCasedPropertiesDeep<{line1: {line2: [{line3: string}]
51
51
  ],
52
52
  },
53
53
  };
54
+
55
+ const splitOnPunctuation: KebabCasedPropertiesDeep<{'user@info': {'user::id': number; 'user::name': string}}, {splitOnPunctuation: true}> = {
56
+ 'user-info': {
57
+ 'user-id': 1,
58
+ 'user-name': 'Tom',
59
+ },
60
+ };
54
61
  ```
55
62
 
56
63
  @category Change case
@@ -4,7 +4,7 @@ import type {ApplyDefaultOptions} from './internal/index.d.ts';
4
4
  import type {WordsOptions} from './words.d.ts';
5
5
 
6
6
  /**
7
- Convert object properties to kebab case but not recursively.
7
+ Convert top-level object properties to kebab case.
8
8
 
9
9
  This can be useful when, for example, converting some API types from a different style.
10
10
 
@@ -28,6 +28,10 @@ const result: KebabCasedProperties<User> = {
28
28
  const splitOnNumbers: KebabCasedProperties<{line1: string}, {splitOnNumbers: true}> = {
29
29
  'line-1': 'string',
30
30
  };
31
+
32
+ const splitOnPunctuation: KebabCasedProperties<{'foo::bar': string}, {splitOnPunctuation: true}> = {
33
+ 'foo-bar': 'string',
34
+ };
31
35
  ```
32
36
 
33
37
  @category Change case
@@ -38,7 +38,7 @@ type AllKeys = KeysOfUnion<Union>;
38
38
  @category Object
39
39
  */
40
40
  export type KeysOfUnion<ObjectType> =
41
- // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
42
- keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
41
+ // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008
42
+ keyof UnionToIntersection<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>;
43
43
 
44
44
  export {};
@@ -1,3 +1,8 @@
1
+ import type {If} from './if.d.ts';
2
+ import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
3
+ import type {SplitOnRestElement} from './split-on-rest-element.d.ts';
4
+ import type {UnknownArray} from './unknown-array.d.ts';
5
+
1
6
  /**
2
7
  Extract the type of the last element of an array.
3
8
 
@@ -16,21 +21,69 @@ const last2 = lastOf([true, false, 'baz', 10]);
16
21
  //=> 10
17
22
  ```
18
23
 
24
+ Note: When the array ends with an optional or rest element, the last element's position becomes ambiguous. In such cases, the result is a union of the types of all elements that could potentially be the last element of the array.
25
+
26
+ @example
27
+ ```
28
+ import type {LastArrayElement} from 'type-fest';
29
+
30
+ type A = LastArrayElement<[string, number?, bigint?]>;
31
+ //=> bigint | number | string
32
+
33
+ type B = LastArrayElement<[string, number, bigint?, ...boolean[]]>;
34
+ //=> boolean | bigint | number
35
+ ```
36
+
37
+ Note: If empty array is a valid value for the array type, the result includes an `undefined`. This aligns with the runtime behavior of `[].at(-1)`.
38
+
39
+ @example
40
+ ```
41
+ import type {LastArrayElement} from 'type-fest';
42
+
43
+ type A = LastArrayElement<[]>;
44
+ //=> undefined
45
+
46
+ // `[]` is assignable to `string[]`
47
+ type B = LastArrayElement<string[]>;
48
+ //=> string | undefined
49
+
50
+ // `[]` is assignable to `[string?, number?]`
51
+ type C = LastArrayElement<[string?, number?]>;
52
+ //=> number | string | undefined
53
+
54
+ // `[]` is assignable to [string?, number?, ...bigint[]]`
55
+ type D = LastArrayElement<[string?, number?, ...bigint[]]>;
56
+ //=> bigint | number | string | undefined
57
+ ```
58
+
19
59
  @category Array
20
60
  @category Template literal
21
61
  */
22
- export type LastArrayElement<Elements extends readonly unknown[], ElementBeforeTailingSpreadElement = never> =
23
- // If the last element of an array is a spread element, the `LastArrayElement` result should be `'the type of the element before the spread element' | 'the type of the spread element'`.
24
- Elements extends readonly []
25
- ? ElementBeforeTailingSpreadElement
26
- : Elements extends readonly [...infer U, infer V]
27
- ? V
28
- : Elements extends readonly [infer U, ...infer V]
29
- // If we return `V[number] | U` directly, it would be wrong for `[[string, boolean, object, ...number[]]`.
30
- // So we need to recurse type `V` and carry over the type of the element before the spread element.
31
- ? LastArrayElement<V, U>
32
- : Elements extends ReadonlyArray<infer U>
33
- ? U | ElementBeforeTailingSpreadElement
34
- : never;
62
+ export type LastArrayElement<TArray extends UnknownArray> =
63
+ IfNotAnyOrNever<TArray, {
64
+ ifNot: TArray extends UnknownArray // For distributing `TArray`
65
+ ? SplitOnRestElement<TArray> extends readonly [infer BeforeRest extends UnknownArray, infer Rest extends UnknownArray, infer AfterRest extends UnknownArray]
66
+ ? _LastArrayElement<BeforeRest, Rest, AfterRest>
67
+ : never
68
+ : never;
69
+ }>;
70
+
71
+ type _LastArrayElement<BeforeRest extends UnknownArray, Rest extends UnknownArray, AfterRest extends UnknownArray> =
72
+ AfterRest extends readonly [...any, infer Last] // Note there are no optional elements in `AfterRest`.
73
+ ? Last // If there's a `Last` in `AfterRest`, then that's the result.
74
+ : Rest[number] | BeforeRestLastElement<BeforeRest>; // Otherwise, the result is union of the `Rest` element and the last element in `BeforeRest`.
75
+
76
+ type BeforeRestLastElement<BeforeRest extends UnknownArray, Accumulator = never> =
77
+ BeforeRest extends readonly []
78
+ ? Accumulator | undefined
79
+ : BeforeRest extends readonly [...any, infer Last]
80
+ ? Last | Accumulator
81
+ : BeforeRest extends readonly [...infer Rest, (infer Last)?]
82
+ ? BeforeRestLastElement<
83
+ Rest,
84
+ // Add `undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
85
+ Last | Accumulator | If<IsExactOptionalPropertyTypesEnabled, never, undefined>
86
+ >
87
+ : never;
35
88
 
36
89
  export {};
@@ -1,7 +1,7 @@
1
1
  import type {GreaterThan} from './greater-than.d.ts';
2
2
 
3
3
  /**
4
- Returns a boolean for whether a given number is less than or equal to another number.
4
+ Returns a boolean for whether a given number is less than or equal to another number.
5
5
 
6
6
  @example
7
7
  ```
@@ -1,5 +1,5 @@
1
1
  /**
2
- Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the {@link Primitive | primitive type} it belongs to, or `never` if it's not a primitive.
2
+ Given a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) return the [primitive type](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) it belongs to, or `never` if it's not a primitive.
3
3
 
4
4
  Use-case: Working with generic types that may be literal types.
5
5
 
@@ -3,7 +3,7 @@ import type {Primitive} from './primitive.d.ts';
3
3
  export type _LiteralStringUnion<T> = LiteralUnion<T, string>;
4
4
 
5
5
  /**
6
- Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
6
+ Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
7
7
 
8
8
  Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
9
9
 
@@ -18,9 +18,9 @@ type Writable<TArray extends UnknownArray> = {-readonly [Key in keyof TArray]: T
18
18
 
19
19
  // Using the default `ArrayTail` type causes issues, refer https://github.com/sindresorhus/type-fest/pull/1175/files#r2134694728.
20
20
  type ArrayTail<TArray extends UnknownArray> = TArray extends unknown // For distributing `TArray`
21
- ? keyof TArray & `${number}` extends never
22
- ? []
23
- : Writable<_ArrayTail<TArray>>
21
+ ? '0' extends keyof TArray
22
+ ? Writable<_ArrayTail<TArray>>
23
+ : []
24
24
  : never; // Should never happen
25
25
 
26
26
  type SimplifyDeepExcludeArray<T> = SimplifyDeep<T, UnknownArray>;
@@ -38,8 +38,8 @@ exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
38
38
  @category Object
39
39
  */
40
40
  export type MergeExclusive<FirstType, SecondType> =
41
- (FirstType | SecondType) extends object ?
42
- (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
43
- FirstType | SecondType;
41
+ (FirstType | SecondType) extends object
42
+ ? (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType)
43
+ : FirstType | SecondType;
44
44
 
45
45
  export {};
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
4
4
  type Recursive<T> = Array<Recursive<T>>;
5
5
 
6
6
  /**
7
- Creates a type that represents a multidimensional array of the given type and dimension.
7
+ Create a type that represents a multidimensional array of the given type and dimension.
8
8
 
9
9
  Use-cases:
10
10
  - Return a n-dimensional array from functions.
@@ -4,7 +4,7 @@ import type {IsEqual} from './is-equal.d.ts';
4
4
  type Recursive<T> = ReadonlyArray<Recursive<T>>;
5
5
 
6
6
  /**
7
- Creates a type that represents a multidimensional readonly array that of the given type and dimension.
7
+ Create a type that represents a multidimensional readonly array of the given type and dimension.
8
8
 
9
9
  Use-cases:
10
10
  - Return a n-dimensional array from functions.
@@ -0,0 +1,102 @@
1
+ import type {BuiltIns, HasMultipleCallSignatures} from './internal/type.d.ts';
2
+ import type {IsNever} from './is-never.d.ts';
3
+ import type {Simplify} from './simplify.d.ts';
4
+
5
+ /**
6
+ Recursively removes `null` and `undefined` from the specified type.
7
+
8
+ Use-cases:
9
+ - Normalizing data received from external sources where `null`/`undefined` have been cleaned.
10
+ - Creating non-nullable variants of deeply nested types.
11
+
12
+ NOTE: Optional modifiers (`?`) are not removed from properties. For example, `NonNullableDeep<{foo?: string | null | undefined}>` will result in `{foo?: string}`. To remove both optional modifiers and nullables, use {@link RequiredDeep} in conjunction with this type.
13
+
14
+ @example
15
+ ```
16
+ import type {NonNullableDeep} from 'type-fest';
17
+
18
+ type UserDraft = {
19
+ name: string | null;
20
+ address: {
21
+ city: string | undefined;
22
+ postalCode: string | null;
23
+ landmark?: string | undefined;
24
+ };
25
+ tags: Array<string | null>;
26
+ visits: Map<string | null, {
27
+ date: Date | null;
28
+ notes: Set<string | undefined>;
29
+ }>;
30
+ };
31
+
32
+ type User = NonNullableDeep<UserDraft>;
33
+ //=> {
34
+ // name: string;
35
+ // address: {
36
+ // city: string;
37
+ // postalCode: string;
38
+ // landmark?: string;
39
+ // };
40
+ // tags: string[];
41
+ // visits: Map<string, {
42
+ // date: Date;
43
+ // notes: Set<string>;
44
+ // }>;
45
+ // }
46
+ ```
47
+
48
+ @example
49
+ ```
50
+ import type {NonNullableDeep} from 'type-fest';
51
+
52
+ type ArrayExample = NonNullableDeep<[{a: number | undefined}, ...Array<{b: string | null}>]>;
53
+ //=> [{a: number}, ...{b: string}[]]
54
+
55
+ type MapExample = NonNullableDeep<{a: Map<{a: string | null}, {c: number | undefined}>}>;
56
+ //=> {a: Map<{a: string}, {c: number}>}
57
+
58
+ type SetExample = NonNullableDeep<Set<{a: string | null}> | null | undefined>;
59
+ //=> Set<{a: string}>
60
+
61
+ type PromiseExample = NonNullableDeep<{a: Promise<{b: string | null}>}>;
62
+ //=> {a: Promise<{b: string}>}
63
+
64
+ type FunctionExample = NonNullableDeep<(a: string | null) => number | undefined>;
65
+ //=> (a: string) => number
66
+ ```
67
+
68
+ @category Utilities
69
+ @category Object
70
+ @category Array
71
+ @category Set
72
+ @category Map
73
+ */
74
+ export type NonNullableDeep<T> =
75
+ T extends BuiltIns | (new (...arguments_: any[]) => unknown)
76
+ ? Exclude<T, null | undefined> // `Exclude` is used instead of `NonNullable` because `NonNullable<void>` results in `void & {}`.
77
+ : T extends Map<infer KeyType, infer ValueType>
78
+ ? Map<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
79
+ : T extends Set<infer ItemType>
80
+ ? Set<NonNullableDeep<ItemType>>
81
+ : T extends ReadonlyMap<infer KeyType, infer ValueType>
82
+ ? ReadonlyMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
83
+ : T extends ReadonlySet<infer ItemType>
84
+ ? ReadonlySet<NonNullableDeep<ItemType>>
85
+ : T extends WeakMap<infer KeyType, infer ValueType>
86
+ ? WeakMap<NonNullableDeep<KeyType>, NonNullableDeep<ValueType>>
87
+ : T extends WeakSet<infer ItemType>
88
+ ? WeakSet<NonNullableDeep<ItemType>>
89
+ : T extends Promise<infer ValueType>
90
+ ? Promise<NonNullableDeep<ValueType>>
91
+ : T extends (...arguments_: any[]) => unknown
92
+ ? HasMultipleCallSignatures<T> extends true
93
+ ? T
94
+ : ((...arguments_: NonNullableDeep<Parameters<T>>) => NonNullableDeep<ReturnType<T>>)
95
+ & (IsNever<keyof T> extends true
96
+ ? unknown
97
+ : NonNullableDeep<Simplify<T>>) // `Simplify` removes the call signature
98
+ : T extends object
99
+ ? {[P in keyof T]: NonNullableDeep<T[P]>}
100
+ : unknown;
101
+
102
+ export {};
@@ -121,9 +121,9 @@ declare function setPercentage<T extends number>(length: Float<T>): void;
121
121
  @category Numeric
122
122
  */
123
123
  export type Float<T> =
124
- T extends unknown // To distributive type
125
- ? IsFloat<T> extends true ? T : never
126
- : never; // Never happens
124
+ T extends unknown // To distributive type
125
+ ? IsFloat<T> extends true ? T : never
126
+ : never; // Never happens
127
127
 
128
128
  /**
129
129
  A negative (`-∞ < x < 0`) `number` that is not an integer.
@@ -90,22 +90,27 @@ Note: If you want a simple merge where properties from the second object always
90
90
  @category Object
91
91
  */
92
92
  export type ObjectMerge<First extends object, Second extends object> =
93
- IfNotAnyOrNever<First, IfNotAnyOrNever<Second, First extends unknown // For distributing `First`
94
- ? Second extends unknown // For distributing `Second`
95
- ? First extends MapsSetsOrArrays
96
- ? unknown
97
- : Second extends MapsSetsOrArrays
98
- ? unknown
99
- : _ObjectMerge<
100
- First,
101
- Second,
102
- NormalizedLiteralKeys<First>,
103
- NormalizedLiteralKeys<Second>,
104
- IsExactOptionalPropertyTypesEnabled extends true ? Required<First> : First,
105
- IsExactOptionalPropertyTypesEnabled extends true ? Required<Second> : Second
106
- >
107
- : never // Should never happen
108
- : never>, First & Second>; // Should never happen
93
+ IfNotAnyOrNever<First, {
94
+ ifNot: IfNotAnyOrNever<Second, {
95
+ ifNot: First extends unknown // For distributing `First`
96
+ ? Second extends unknown // For distributing `Second`
97
+ ? First extends MapsSetsOrArrays
98
+ ? unknown
99
+ : Second extends MapsSetsOrArrays
100
+ ? unknown
101
+ : _ObjectMerge<
102
+ First,
103
+ Second,
104
+ NormalizedLiteralKeys<First>,
105
+ NormalizedLiteralKeys<Second>,
106
+ IsExactOptionalPropertyTypesEnabled extends true ? Required<First> : First,
107
+ IsExactOptionalPropertyTypesEnabled extends true ? Required<Second> : Second
108
+ >
109
+ : never // Should never happen
110
+ : never; // Should never happen
111
+ }>;
112
+ ifAny: First & Second;
113
+ }>;
109
114
 
110
115
  type _ObjectMerge<
111
116
  First extends object,